Kaydet (Commit) 27557a7a authored tarafından hayashi's avatar hayashi Kaydeden (comit) Tim Graham

Fixed #28857 -- Fixed invalid SQL when using Cast with complex expressions on PostgreSQL.

üst b902878f
...@@ -21,7 +21,9 @@ class Cast(Func): ...@@ -21,7 +21,9 @@ class Cast(Func):
def as_postgresql(self, compiler, connection): def as_postgresql(self, compiler, connection):
# CAST would be valid too, but the :: shortcut syntax is more readable. # CAST would be valid too, but the :: shortcut syntax is more readable.
return self.as_sql(compiler, connection, template='%(expressions)s::%(db_type)s') # 'expressions' is wrapped in parentheses in case it's a complex
# expression.
return self.as_sql(compiler, connection, template='(%(expressions)s)::%(db_type)s')
class Coalesce(Func): class Coalesce(Func):
......
import datetime import datetime
import decimal import decimal
import unittest
from django.db import models from django.db import connection, models
from django.db.models import Avg
from django.db.models.expressions import Value from django.db.models.expressions import Value
from django.db.models.functions import Cast from django.db.models.functions import Cast
from django.test import TestCase, ignore_warnings, skipUnlessDBFeature from django.test import (
TestCase, ignore_warnings, override_settings, skipUnlessDBFeature,
)
from .models import Author from .models import Author
...@@ -60,3 +64,13 @@ class CastTests(TestCase): ...@@ -60,3 +64,13 @@ class CastTests(TestCase):
cast_float = numbers.get().cast_float cast_float = numbers.get().cast_float
self.assertIsInstance(cast_float, float) self.assertIsInstance(cast_float, float)
self.assertEqual(cast_float, 0.125) self.assertEqual(cast_float, 0.125)
@unittest.skipUnless(connection.vendor == 'postgresql', 'PostgreSQL test')
@override_settings(DEBUG=True)
def test_expression_wrapped_with_parentheses_on_postgresql(self):
"""
The SQL for the Cast expression is wrapped with parentheses in case
it's a complex expression.
"""
list(Author.objects.annotate(cast_float=Cast(Avg('age'), models.FloatField())))
self.assertIn('(AVG("db_functions_author"."age"))::double precision', connection.queries[-1]['sql'])
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment