Skip to content

Commit

Permalink
Bump version to 3.32.0
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremyevans committed Feb 1, 2012
1 parent 1cce888 commit 1d5660a
Show file tree
Hide file tree
Showing 3 changed files with 204 additions and 2 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
=== HEAD
=== 3.32.0 (2012-02-01)

* Make serialization_modification_detection plugin work correctly with new objects and after saving existing objects (jeremyevans) (#432)

Expand Down
202 changes: 202 additions & 0 deletions doc/release_notes/3.32.0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
= New Features

* Prepared statements now support :map and :to_hash prepared
statement types. The main reason for this is that certain
extensions (e.g. sequel_pg) optimize map/to_hash calls, and
there previously was not a way to use prepared statements
with the map/to_hash optimizations.

* Sequel.empty_array_handle_nulls has been added to change how
IN/NOT IN operations with an empty array are handled. See
the Backwards Compatibility section for details.

* 5 new association options have been added that allow you to
define associations where the underlying columns clash with
standard ruby method names:

many_to_one :primary_key_method
one_to_many :key_method
one_to_many :primary_key_column
many_to_many :left_primary_key_column
many_to_many :right_primary_key_method

Using these new options, you can now define associations
that work correctly when the underlying primary/foreign key
columns clash with existing ruby method names. See the RDoc
for details.

* A use_after_commit_rollback setting has been added to models.
This defaults to true, but can be set to false for performance
or to allow models to be used in prepared transactions
(which don't support after_commit/after_rollback).

* Dataset#update_ignore has been added when connecting to MySQL,
enabling use of the UPDATE IGNORE syntax to skip updating a row
if the update would cause a unique constraint to be violated.

* Database#indexes is now supported when connecting to Microsoft
SQL Server.

* On Microsoft SQL Server, the :include option is now supported
when creating indexes, for storing column values in the index,
which can be used by the query optimizer.

= Other Improvements

* The filtering/excluding by associations code now uses qualified
identifiers instead of unqualified identifiers, which allows it
to avoid ambiguous column names if you are doing your own joins.

* Virtual row blocks that return arrays are now handled correctly
in Dataset#select_map/select_order_map.

* Dataset#select_map/select_order_map can now take both a block
argument as well as a regular argument.

* Dataset#select_order_map now handles virtual row blocks that
return ordered expressions.

* Database#table_exists? should no longer generate false negatives
if you only have permission to retrieve some column values but
not all. Note that if you lack permission to SELECT from the
table itself, table_exists? can still generate false negatives.

* The active_model plugin now supports ActiveModel 3.2, by adding
support for to_partial_path.

* The serialization_modification_detection plugin now handles
changed_columns correctly both for new objects and after saving
objects.

* The serialization plugin now clears the deserialized values when
it does the automatic refresh after saving a new object, mostly for
consistency. You can use the skip_create_refresh plugin to skip
refreshing when creating a new model object.

* Column default values are now wrapped in parentheses on SQLite,
which fixes some cases such as when the default is an SQL function
call.

* Alter table emulation now works correctly on SQLite when foreign
keys reference the table being altered. The emulation requires
a renaming/deleting the existing table and creating a new table,
which can break foreign key references. Sequel now disables the
foreign key PRAGMA when altering tables, so SQLite won't track
the table renames and break the foreign key relationships.

* The set_column_type table alteration method no longer modifies
default values and NULL/NOT NULL settings on Microsoft SQL
Server, H2, and SQLite.

* On MySQL, Time/DateTime columns now use the timestamp type if the
default value is Sequel::CURRENT_TIMESTAMP, since it is currently
impossible for MySQL to have a non-constant default for a
datetime column (without using a workaround like a trigger).

* Metadata methods such as tables, views, and view_exists? are now
handled correctly on Oracle if custom identifier input methods
are used.

* Sequel now ignores errors that occur when attempting to get
information on column defaults in Oracle (which can happen if you
lack permission to the appropriate table). Previously, such errors
would cause the schema parser to raise an error, now, the schema
information is just returned without default information.

* Database#indexes now skips the primary key index when connecting to
DB2, Derby, HSQLDB, and Oracle via the jdbc adapter.

* Database#indexes now works correctly on DB2.

* The progress adapter has been fixed, it had been broken since the
dataset literalization refactoring.

* Dataset#naked! now works correctly. Previously, it just returned
the receiver unmodified.

* Dataset#paginate! has been removed, as it was broken.

* The query extension no longer breaks Dataset#clone if an argument
is not given.

* Transaction related queries are no longer logged twice in the mock
adapter.

= Backwards Compatibility

* Sequel's default handling of NOT IN operators with an empty array
of values has changed, which can change which rows are returned for
such queries.

Previously, Sequel was inconsistent in that it tried to handle NULL
values correctly in the IN case, but not in the NOT IN case. Now,
it defaults to handling NULL values correctly in both cases:

# 3.31.0
DB[:a].where(:b=>[])
# SELECT * FROM a WHERE (b != b)
DB[:a].exclude(:b=>[])
# SELECT * FROM a WHERE (1 = 1)

# 3.32.0
DB[:a].where(:b=>[])
# SELECT * FROM a WHERE (b != b)
DB[:a].exclude(:b=>[])
# SELECT * FROM a WHERE (b = b)

The important change in behavior is that in the NOT IN case, if
the left hand argument is NULL, the filter returns NULL instead
of true. This has the potential to change query results.

"Correct" here is really an opinion and not a fact, as there are
valid arguments for the alternative behavior:

DB[:a].where(:b=>[])
# SELECT * FROM a WHERE (1 = 0)
DB[:a].exclude(:b=>[])
# SELECT * FROM a WHERE (1 = 1)

The difference is that the "correct" NULL behavior is more
consistent with the non-empty array cases. For example, if b is
NULL:

# "Correct" NULL handling
# Empty array: where(:b=>[])
WHERE (b != b) # NULL
WHERE (b = b) # NULL
# Non-empty array: where(:b=>[1, 2])
WHERE (b IN (1, 2)) # NULL
WHERE (b NOT IN (1, 2)) # NULL

# Static boolean handling
# Empty array: where(:b=>[])
WHERE (1 = 0) # false
WHERE (1 = 1) # true
# Non-empty array: where(:b=>[1, 2])
WHERE (b IN (1, 2)) # NULL
WHERE (b NOT IN (1, 2)) # NULL

Sequel chooses to default to behavior consistent with the non-empty
array cases (similar to SQLAlchemy). However, there are two
downsides to this handling. The first is that some databases with
poor optimizers (e.g. MySQL) might do a full table scan with the
default syntax. The second is that the static boolean handling may
be generally perferable, if you believe that IN/NOT IN with an
empty array should always be true or false and never NULL even if
the left hand argument is NULL.

As there really isn't a truly correct answer in this case, Sequel
defaults to the "correct" NULL handling, and allows you to switch
to the static boolean handling via:

Sequel.empty_array_handle_nulls = false

This is currently a global setting, it may be made Database or
Dataset specific later if requested. Also, it is possible the
default will switch in the future, so if you care about a specific
handling, you should set your own default.

* Database#table_exists? now only rescues Sequel::DatabaseErrors
instead of StandardErrors, so it's possible it will raise errors
instead of returning false on custom adapters that don't wrap
their errors correctly.
2 changes: 1 addition & 1 deletion lib/sequel/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Sequel
MAJOR = 3
# The minor version of Sequel. Bumped for every non-patch level
# release, generally around once a month.
MINOR = 31
MINOR = 32
# The tiny version of Sequel. Usually 0, only bumped for bugfix
# releases that fix regressions from previous versions.
TINY = 0
Expand Down

0 comments on commit 1d5660a

Please sign in to comment.