Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fixed #11442 -- Postgresql backend casts all inet types to text #1160

Merged
merged 1 commit into from

2 participants

@erikr
Collaborator

No description provided.

@aaugustin aaugustin merged commit f746718 into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
10 django/db/backends/__init__.py
@@ -765,12 +765,12 @@ def fetch_returned_insert_id(self, cursor):
"""
return cursor.fetchone()[0]
- def field_cast_sql(self, db_type):
+ def field_cast_sql(self, db_type, internal_type):
"""
- Given a column type (e.g. 'BLOB', 'VARCHAR'), returns the SQL necessary
- to cast it before using it in a WHERE statement. Note that the
- resulting string should contain a '%s' placeholder for the column being
- searched against.
+ Given a column type (e.g. 'BLOB', 'VARCHAR'), and an internal type
+ (e.g. 'GenericIPAddressField'), returns the SQL necessary to cast it
+ before using it in a WHERE statement. Note that the resulting string
+ should contain a '%s' placeholder for the column being searched against.
"""
return '%s'
View
2  django/db/backends/oracle/base.py
@@ -254,7 +254,7 @@ def drop_sequence_sql(self, table):
def fetch_returned_insert_id(self, cursor):
return int(cursor._insert_id_var.getvalue())
- def field_cast_sql(self, db_type):
+ def field_cast_sql(self, db_type, internal_type):
if db_type and db_type.endswith('LOB'):
return "DBMS_LOB.SUBSTR(%s)"
else:
View
4 django/db/backends/postgresql_psycopg2/operations.py
@@ -78,8 +78,8 @@ def lookup_cast(self, lookup_type):
return lookup
- def field_cast_sql(self, db_type):
- if db_type == 'inet':
+ def field_cast_sql(self, db_type, internal_type):
+ if internal_type == "GenericIPAddressField" or internal_type == "IPAddressField":
return 'HOST(%s)'
return '%s'
View
8 django/db/models/sql/where.py
@@ -174,6 +174,8 @@ def make_atom(self, child, qn, connection):
it.
"""
lvalue, lookup_type, value_annotation, params_or_value = child
+ field_internal_type = lvalue.field.get_internal_type() if lvalue.field else None
+
if isinstance(lvalue, Constraint):
try:
lvalue, params = lvalue.process(lookup_type, params_or_value, connection)
@@ -187,7 +189,7 @@ def make_atom(self, child, qn, connection):
if isinstance(lvalue, tuple):
# A direct database column lookup.
- field_sql, field_params = self.sql_for_columns(lvalue, qn, connection), []
+ field_sql, field_params = self.sql_for_columns(lvalue, qn, connection, field_internal_type), []
else:
# A smart object with an as_sql() method.
field_sql, field_params = lvalue.as_sql(qn, connection)
@@ -257,7 +259,7 @@ def make_atom(self, child, qn, connection):
raise TypeError('Invalid lookup_type: %r' % lookup_type)
- def sql_for_columns(self, data, qn, connection):
+ def sql_for_columns(self, data, qn, connection, internal_type=None):
"""
Returns the SQL fragment used for the left-hand side of a column
constraint (for example, the "T1.foo" portion in the clause
@@ -268,7 +270,7 @@ def sql_for_columns(self, data, qn, connection):
lhs = '%s.%s' % (qn(table_alias), qn(name))
else:
lhs = qn(name)
- return connection.ops.field_cast_sql(db_type) % lhs
+ return connection.ops.field_cast_sql(db_type, internal_type) % lhs
def relabel_aliases(self, change_map):
"""
View
4 tests/string_lookup/tests.py
@@ -73,9 +73,11 @@ def test_ipaddress_on_postgresql(self):
"""
Regression test for #708
- "like" queries on IP address fields require casting to text (on PostgreSQL).
+ "like" queries on IP address fields require casting with HOST() (on PostgreSQL).
"""
a = Article(name='IP test', text='The body', submitted_from='192.0.2.100')
a.save()
self.assertEqual(repr(Article.objects.filter(submitted_from__contains='192.0.2')),
repr([a]))
+ # Test that the searches do not match the subnet mask (/32 in this case)
+ self.assertEqual(Article.objects.filter(submitted_from__contains='32').count(), 0)
Something went wrong with that request. Please try again.