Skip to content

Commit

Permalink
Fix literalization of boolean values in filters on MSSQL
Browse files Browse the repository at this point in the history
Similar changes here as in SQLite.  It's very unforunate that
SQL 92 didn't specify a boolean data type.
  • Loading branch information
jeremyevans committed May 16, 2011
1 parent 105e939 commit ffccd84
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 3 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG
Expand Up @@ -4,7 +4,7 @@

* Add support for filtering and excluding by association datasets (jeremyevans)

* Fix literalization of boolean values in filters on SQLite (jeremyevans)
* Fix literalization of boolean values in filters on SQLite and MSSQL (jeremyevans)

* Add support for filtering and excluding by multiple associations (jeremyevans)

Expand Down
39 changes: 39 additions & 0 deletions lib/sequel/adapters/shared/mssql.rb
Expand Up @@ -242,6 +242,29 @@ def initialize(db, opts={})
@mssql_unicode_strings = db.mssql_unicode_strings
end

# Ugly hack. While MSSQL supports TRUE and FALSE values, you can't
# actually specify them directly in SQL. Unfortunately, you also cannot
# use an integer value when a boolean is required. Also unforunately, you
# cannot use an expression that yields a boolean type in cases where in an
# integer type is needed, such as inserting into a bit field (the closest thing
# MSSQL has to a boolean).
#
# In filters, SQL::BooleanConstants are used more, while in other places
# the ruby true/false values are used more, so use expressions that return booleans
# for SQL::BooleanConstants, and 1/0 for other places.
# The correct fix for this would require separate literalization paths for
# filters compared to other values, but that's more work than I want to do right now.
def boolean_constant_sql(constant)
case constant
when true
'(1 = 1)'
when false
'(1 = 0)'
else
super
end
end

# MSSQL uses + for string concatenation, and LIKE is case insensitive by default.
def complex_expression_sql(op, args)
case op
Expand Down Expand Up @@ -452,6 +475,22 @@ def delete_with_sql(sql)
alias insert_with_sql delete_with_sql
alias update_with_sql delete_with_sql

# Special case when true or false is provided directly to filter.
def filter_expr(expr)
if block_given?
super
else
case expr
when true
Sequel::TRUE
when false
Sequel::FALSE
else
super
end
end
end

# MSSQL raises an error if you try to provide more than 3 decimal places
# for a fractional timestamp. This probably doesn't work for smalldatetime
# fields.
Expand Down
3 changes: 1 addition & 2 deletions lib/sequel/adapters/shared/sqlite.rb
Expand Up @@ -345,8 +345,7 @@ module DatasetMethods
# In filters, SQL::BooleanConstants are used more, while in other places
# the ruby true/false values are used more, so use 1/0 for SQL::BooleanConstants.
# The correct fix for this would require separate literalization paths for
# filters compared to other values, but doing that just to work around shortcomings
# in SQLite doesn't appeal to me.
# filters compared to other values, but that's more work than I want to do right now.
def boolean_constant_sql(constant)
case constant
when true
Expand Down

0 comments on commit ffccd84

Please sign in to comment.