rails/rails — pull request #7584 by keithgabryelski (2012-09-10 02:29:33+00:00)
Title: partitioning updates working

basic work for supporting partitioned tables in postgresql

these changes are associated with this pull request: https://github.com/rails/rails/pull/7573
which were changes associated with rails 3.2.8.

If I were to sum up the work, it would be:

* provide an instance method arel_table used for any operation that has access to the instance should use the instance method to acquire an arel_table associated with the current models attributes.
* alter class method arel_table to handle parameters, with no parameters do original work -- with parameters associate the table with the specific partitioned table determined by key attributes
* provide methods to manage key attributes and values (these are the fields the db table is partitioned on)
* provide an instance method table_name which calls the altered class method table_name which now takes attribute values that should determine the specific partitioned table to name
* bunch of helper methods in postgresql connection area associated with schema management. this is for reasons 1) create_schema seems like a useful method, 2) adding foreign key is needed because in postgres child partitions need to manage the foreign key references, 3) some sequence method changes to support tables in non-public (well non search path) schema: this is probably generally useful work as rails seems broken about non-public schemas
* change any self.class.arel_table to self.arel_table
* create is a little weird because it needs to acquire the primary key if it isn't supplied (for instance ID where your need to fetch from the sequence -- for this work to be complete we need to supply the model instance method "prefetch_primary_key?" instead of it being on connection since prefetching isn't needed for any tables that aren't partitioned by a primary key)
* some helper methods for finds (from_partition(*x)) which we've found useful in our day to day coding. this method just sets the table name (this is useful because find from the parent table even when partition keys are provided can take an inordinate time if the number of child tables is large -- so specifying the specific child table is useful).

the rest of the code to support partitioning is here: https://github.com/fiksu/partitioned/tree/rails-3-2-8-patching -- you'll need to pull from that branch (which doesn't try to patch rails -- so use it with this pull request). the master branch patches rails 3.2.8 correctly -- you can use it on your own. The current rubygem of partitioned patches rails in a different (and more conservative way) -- I don't think you should look at that code.

You could probably remove a bunch of stuff to make this code faster for the common non-partitioned case.

* instance arel_table could just call class method arel_table
* self.class.arel_table could just do the old work
* instance table_name could just call class method table_name which did just the old work

then one might provide fixups for those methods for models where partitioning is desired.

I think the ugliest part of this code is update -- although I haven't walked down this path, it would seem the best way to manage this would be to add a hook to attribute modifications and fix up the all arel_tables that the attributes point to if the partitioned key values changes

I'm willing to help in any way that makes sense to support partitioning in a future rails version.