diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
index 78dbbc6..a9cfc4b 100644
|
a
|
b
|
class BaseDatabaseOperations(object):
|
| 526 | 526 | """ |
| 527 | 527 | return "%s" |
| 528 | 528 | |
| | 529 | def decimal_cast_sql(self, max_digits, decimal_places): |
| | 530 | """ |
| | 531 | FIXME: documentation |
| | 532 | """ |
| | 533 | return "%s" |
| | 534 | |
| 529 | 535 | def deferrable_sql(self): |
| 530 | 536 | """ |
| 531 | 537 | Returns the SQL necessary to make a constraint "initially deferred" |
diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py
index f24df93..940200b 100644
|
a
|
b
|
class DatabaseOperations(BaseDatabaseOperations):
|
| 222 | 222 | return "(%s %s INTERVAL '%d 0:0:%d:%d' DAY_MICROSECOND)" % (sql, connector, |
| 223 | 223 | timedelta.days, timedelta.seconds, timedelta.microseconds) |
| 224 | 224 | |
| | 225 | def decimal_cast_sql(self, max_digits, decimal_places): |
| | 226 | """ |
| | 227 | FIXME: documentation |
| | 228 | """ |
| | 229 | return "CAST(%%s AS DECIMAL(%d, %d))" % (max_digits, decimal_places) |
| | 230 | |
| 225 | 231 | def drop_foreignkey_sql(self): |
| 226 | 232 | return "DROP FOREIGN KEY" |
| 227 | 233 | |
diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py
index 3e4b352..eff1a12 100644
|
a
|
b
|
from __future__ import absolute_import
|
| 6 | 6 | |
| 7 | 7 | import collections |
| 8 | 8 | import datetime |
| | 9 | import decimal |
| | 10 | import re |
| 9 | 11 | from itertools import repeat |
| 10 | 12 | |
| 11 | 13 | from django.utils import tree |
| … |
… |
from django.utils.six.moves import xrange
|
| 18 | 20 | AND = 'AND' |
| 19 | 21 | OR = 'OR' |
| 20 | 22 | |
| | 23 | # Extract precision from decimal field info |
| | 24 | DECIMAL_PRECISION_RE = re.compile(r'^\D+(\d+)\D+(\d+)\D+$') |
| | 25 | |
| 21 | 26 | class EmptyShortCircuit(Exception): |
| 22 | 27 | """ |
| 23 | 28 | Internal exception used to indicate that a "matches nothing" node should be |
| … |
… |
class WhereNode(tree.Node):
|
| 62 | 67 | # here in the future (using Python types is suggested for consistency). |
| 63 | 68 | if isinstance(value, datetime.datetime): |
| 64 | 69 | value_annotation = datetime.datetime |
| | 70 | elif isinstance(value, decimal.Decimal): |
| | 71 | value_annotation = decimal.Decimal |
| 65 | 72 | elif hasattr(value, 'value_annotation'): |
| 66 | 73 | value_annotation = value.value_annotation |
| 67 | 74 | else: |
| … |
… |
class WhereNode(tree.Node):
|
| 176 | 183 | |
| 177 | 184 | if value_annotation is datetime.datetime: |
| 178 | 185 | cast_sql = connection.ops.datetime_cast_sql() |
| | 186 | elif value_annotation is decimal.Decimal: |
| | 187 | # lvalue[2] holds something like 'numeric(12, 6)' |
| | 188 | precision_match = DECIMAL_PRECISION_RE.match(lvalue[2]) |
| | 189 | max_digits, dec_places = [int(i) for i in precision_match.groups()] |
| | 190 | cast_sql = connection.ops.decimal_cast_sql(max_digits, dec_places) |
| | 191 | del precision_match |
| | 192 | del max_digits |
| | 193 | del dec_places |
| 179 | 194 | else: |
| 180 | 195 | cast_sql = '%s' |
| 181 | 196 | |