Commit 207117ae authored by Anssi Kääriäinen's avatar Anssi Kääriäinen
Browse files

[1.5.x] Fixed #20091 -- Oracle null promotion for empty strings

Backpatch of e17fa9e8
parent 5e2bb122
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -1106,7 +1106,14 @@ class Query(object):
            # If value is a query expression, evaluate it
            value = SQLEvaluator(value, self, reuse=can_reuse)
            having_clause = value.contains_aggregate

        # For Oracle '' is equivalent to null. The check needs to be done
        # at this stage because join promotion can't be done at compiler
        # stage. Using DEFAULT_DB_ALIAS isn't nice, but it is the best we
        # can do here. Similar thing is done in is_nullable(), too.
        if (connections[DEFAULT_DB_ALIAS].features.interprets_empty_strings_as_nulls and
                lookup_type == 'exact' and value == ''):
            value = True
            lookup_type = 'isnull'
        for alias, aggregate in self.aggregates.items():
            if alias in (parts[0], LOOKUP_SEP.join(parts)):
                entry = self.where_class()
+8 −1
Original line number Diff line number Diff line
@@ -1533,7 +1533,6 @@ class Queries6Tests(TestCase):

        # Nested queries are possible (although should be used with care, since
        # they have performance problems on backends like MySQL.

        self.assertQuerysetEqual(
            Annotation.objects.filter(notes__in=Note.objects.filter(note="n1")),
            ['<Annotation: a1>']
@@ -2142,3 +2141,11 @@ class NullJoinPromotionOrTest(TestCase):
        # so we can use INNER JOIN for it. However, we can NOT use INNER JOIN
        # for the b->c join, as a->b is nullable.
        self.assertEqual(str(qset.query).count('INNER JOIN'), 1)

class EmptyStringPromotionTests(TestCase):
    def test_empty_string_promotion(self):
        qs = RelatedObject.objects.filter(single__name='')
        if connection.features.interprets_empty_strings_as_nulls:
            self.assertIn('LEFT OUTER JOIN', str(qs.query))
        else:
            self.assertNotIn('LEFT OUTER JOIN', str(qs.query))