= New Features

* A one_through_one association type has been added.  This is similar
  to the many_to_many association type in that it uses a join table,
  but it returns a single record instead of an array of records.
  This is designed for cases where the foreign key in the join table
  that references the current table has a unique constraint, or where
  you want to use an order to just pick the first matching record.

  Similarly, the many_through_many plugin now also offers a
  one_through_many association.

* An association_join method has been added to model datasets, for
  setting up joins based on associations.  This basically does the
  same join that eager_graph would do, but does not make the other
  changes that eager_graph makes.

  Unlike eager_graph (which uses LEFT OUTER JOINs by default),
  association_join uses INNER JOINs, but there are also
  association_*_join methods (e.g. association_left_join) for
  using different join types.

  Similar to eager_graph, you can use cascading of associations or
  multiple associations.

    Album.association_join(:artist, :tracks)
    Artist.association_left_join(:albums=>:tracks)

* Dataset#eager_graph_with_options has been added for model
  datasets.  It currently supports a :join_type option, for
  overriding the type of join to use on a per-call basis, as well
  as a :limit_strategy option.  The API is similar to eager_graph,
  except that the associations to eagerly load are passed in as
  a single argument, and it takes an options hash.

  The :limit_strategy option works similarly to the
  :eager_limit_strategy option when eagerly loading.  If set to
  true and the database supports window functions, it will join
  the current dataset to a subquery that uses a window function
  to correctly restrict the join to only those objects that fall
  within the association's limit/offset.

  The :limit_strategy option is not on by default.  It is possible
  for it to perform significantly worse than the default strategy
  (which uses array slicing in ruby).  The :limit_strategy
  significantly changes the SQL used, and can change the results
  of the query if any filters/orders related to the association
  are used.

  It's recommended you only use the :limit_strategy option if you
  are experiencing a bottleneck and you have benchmarked that it
  is faster and still produces the desired results.

    Artist.eager_graph_with_options(:first_10_albums,
      :limit_strategy=>true)
    # SELECT artists.id, artists.name,
    #   first_10_albums.id AS first_10_albums_id,
    #   first_10_albums.name AS first_10_albums_name,
    #   first_10_albums.artist_id,
    #   first_10_albums.release_date
    # FROM artists
    # LEFT OUTER JOIN (
    #   SELECT id, name, artist_id, release_date
    #   FROM (
    #     SELECT *, row_number() OVER (PARTITION BY tracks.album_id)
    #       AS x_sequel_row_number_x
    #     FROM albums
    #   ) AS t1 WHERE (x_sequel_row_number_x <= 10)
    # ) AS first_10_albums ON (first_10_albums.artist_id = artists.id)

* Dataset#full_text_search on PostgreSQL now supports :plain and
  :phrase options.  :plain takes the search terms as a single
  string, and searches for rows where all terms are used.
  :phrase is similar to :plain, but also adds a substring search
  to ensure that the string given appears verbatim in the text.

* A :graph_order association option has been added, for using a
  different order when using eager_graph.  This is mostly
  designed for cases where :order should be qualified in other
  cases, but using a qualification breaks eager_graph because the
  correct qualifier is not known until runtime.

* SQL::AliasedExpression#alias has been added as an alias for #aliaz.

= Other Improvements

* Sequel will now automatically use an eager limit strategy for
  *_one associations that use an :order option.  For associations
  that are truly one-to-one, an :order option is not needed, so it
  only makes sense to have an :order option if the association
  could theoretically return multiple results (in which case an
  eager limit strategy is helpful).

* The queries that Sequel uses to filter by associations when
  those associations have conditions are now simpler and easier
  for the database to execute.

* The queries that Sequel uses for dataset associations now handle
  cases where unqualified identifiers were used in the receiving
  dataset that would be made ambiguous by a join.

* A limit strategy is now used when filtering by associations if
  the association has a limit and the database supports window
  functions.  This allows Sequel to setup a correct filter in
  such cases.

    Artist.where(:first_10_albums=>Album[1]).all
    # SELECT *
    # FROM artists
    # WHERE (artists.id IN (
    #   SELECT albums.artist_id
    #   FROM albums
    #   WHERE ((albums.artist_id IS NOT NULL) AND (albums.id IN (
    #     SELECT id FROM (
    #       SELECT albums.id, row_number() OVER
    #         (PARTITION BY albums.artist_id ORDER BY release_date)
    #         AS x_sequel_row_number_x
    #       FROM albums
    #     ) AS t1
    #     WHERE (x_sequel_row_number_x <= 10)
    #   )) AND (albums.id = 1))))

* A limit strategy is now used in the dataset_associations plugin
  if the association has a limit and the database supports window
  functions.  This makes the resulting datasets return correct
  results.

    Artist.first_10_albums
    # SELECT *
    # FROM albums
    # WHERE ((albums.artist_id IN (
    #   SELECT artists.id FROM artists)
    # ) AND (albums.id IN (
    #   SELECT id FROM (
    #     SELECT albums.id, row_number() OVER
    #       (PARTITION BY albums.artist_id ORDER BY release_date)
    #       AS x_sequel_row_number_x
    #     FROM albums
    #   ) AS t1
    #   WHERE (x_sequel_row_number_x <= 10)
    # )))
    # ORDER BY release_date

* You can now pass symbols with embedded qualifiers or aliases,
  as well as SQL::Identifier, SQL::QualifiedIdentifier, and
  SQL::AliasedExpression objects as the first argument to
  Dataset#graph.

* The nested_attributes plugin now automatically handles presence
  validations on foreign keys when creating associated objects.
  It now sets the foreign key value (or a placeholder value)
  before validating such objects.

* Offsets on *_one associations are now respected when using
  eager_graph.

* eager graphing *_many associations with offsets no longer breaks
  if there are no associated results.

* Database#register_array_type in the pg_array extension now works
  correctly if there is no existing scalar conversion proc for
  the type.

* Unique, foreign key, and not null constraint violations are now
  recognized correctly on SQLite 3.8.2+.

* The odbc adapter now returns fractional seconds in timestamps.

* The obdc/mssql adapter now inputs timestamps with 3 decimal
  places.

= Backwards Compatibility

* The private Model.apply_window_function_eager_limit_strategy
  method has been removed.
