summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshesh <aksheshdoshi@gmail.com>2016-08-08 10:29:08 +0530
committerTim Graham <timograham@gmail.com>2016-08-12 16:58:40 -0400
commit2f19306a125a9253d99b35b276d932e8e24d4e6f (patch)
tree6c505535f15218b2ea0fd57e7d4ae97976662daa
parent72d541b61cd7b0a14f70242e2207fdb3f600c4d5 (diff)
Refs #27030 -- Added index type introspection on PostgreSQL.
-rw-r--r--django/contrib/gis/db/backends/postgis/introspection.py10
-rw-r--r--django/db/backends/base/features.py3
-rw-r--r--django/db/backends/postgresql/features.py1
-rw-r--r--django/db/backends/postgresql/introspection.py8
-rw-r--r--tests/introspection/tests.py5
5 files changed, 21 insertions, 6 deletions
diff --git a/django/contrib/gis/db/backends/postgis/introspection.py b/django/contrib/gis/db/backends/postgis/introspection.py
index 71aa57f163..e4579216f4 100644
--- a/django/contrib/gis/db/backends/postgis/introspection.py
+++ b/django/contrib/gis/db/backends/postgis/introspection.py
@@ -24,14 +24,16 @@ class PostGISIntrospection(DatabaseIntrospection):
# expression over the raster column through the ST_ConvexHull function.
# So the default query has to be adapted to include raster indices.
_get_indexes_query = """
- SELECT DISTINCT attr.attname, idx.indkey, idx.indisunique, idx.indisprimary
- FROM pg_catalog.pg_class c, pg_catalog.pg_class c2,
- pg_catalog.pg_index idx, pg_catalog.pg_attribute attr
- LEFT JOIN pg_catalog.pg_type t ON t.oid = attr.atttypid
+ SELECT DISTINCT attr.attname, idx.indkey, idx.indisunique, idx.indisprimary,
+ am.amname
+ FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index idx,
+ pg_catalog.pg_attribute attr, pg_catalog.pg_type t, pg_catalog.pg_am am
WHERE
c.oid = idx.indrelid
AND idx.indexrelid = c2.oid
AND attr.attrelid = c.oid
+ AND t.oid = attr.atttypid
+ AND c2.relam = am.oid
AND (
attr.attnum = idx.indkey[0] OR
(t.typname LIKE 'raster' AND idx.indkey = '0')
diff --git a/django/db/backends/base/features.py b/django/db/backends/base/features.py
index e3677dd35a..67c34f028f 100644
--- a/django/db/backends/base/features.py
+++ b/django/db/backends/base/features.py
@@ -163,6 +163,9 @@ class BaseDatabaseFeatures(object):
# Can the backend introspect the column order (ASC/DESC) for indexes?
supports_index_column_ordering = True
+ # Can the backend introspect the type of index created?
+ can_introspect_index_type = False
+
# Support for the DISTINCT ON clause
can_distinct_on_fields = False
diff --git a/django/db/backends/postgresql/features.py b/django/db/backends/postgresql/features.py
index a9e1c77480..918dfe7978 100644
--- a/django/db/backends/postgresql/features.py
+++ b/django/db/backends/postgresql/features.py
@@ -22,6 +22,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
can_introspect_autofield = True
can_introspect_ip_address_field = True
can_introspect_small_integer_field = True
+ can_introspect_index_type = True
can_distinct_on_fields = True
can_rollback_ddl = True
supports_combined_alters = True
diff --git a/django/db/backends/postgresql/introspection.py b/django/db/backends/postgresql/introspection.py
index 85ea66f6d1..50c8fb11f0 100644
--- a/django/db/backends/postgresql/introspection.py
+++ b/django/db/backends/postgresql/introspection.py
@@ -36,13 +36,15 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
ignored_tables = []
_get_indexes_query = """
- SELECT attr.attname, idx.indkey, idx.indisunique, idx.indisprimary
+ SELECT attr.attname, idx.indkey, idx.indisunique, idx.indisprimary,
+ am.amname
FROM pg_catalog.pg_class c, pg_catalog.pg_class c2,
- pg_catalog.pg_index idx, pg_catalog.pg_attribute attr
+ pg_catalog.pg_index idx, pg_catalog.pg_attribute attr, pg_catalog.pg_am am
WHERE c.oid = idx.indrelid
AND idx.indexrelid = c2.oid
AND attr.attrelid = c.oid
AND attr.attnum = idx.indkey[0]
+ AND c2.relam = am.oid
AND c.relname = %s"""
def get_field_type(self, data_type, description):
@@ -132,6 +134,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
# row[1] (idx.indkey) is stored in the DB as an array. It comes out as
# a string of space-separated integers. This designates the field
# indexes (1-based) of the fields that have indexes on the table.
+ # row[4] is the type of index, e.g. btree, hash, etc.
# Here, we skip any indexes across multiple fields.
if ' ' in row[1]:
continue
@@ -142,6 +145,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
indexes[row[0]]['primary_key'] = True
if row[2]:
indexes[row[0]]['unique'] = True
+ indexes[row[0]]['type'] = row[4]
return indexes
def get_constraints(self, cursor, table_name):
diff --git a/tests/introspection/tests.py b/tests/introspection/tests.py
index 31b0214704..f01f81e718 100644
--- a/tests/introspection/tests.py
+++ b/tests/introspection/tests.py
@@ -170,6 +170,11 @@ class IntrospectionTests(TransactionTestCase):
def test_get_indexes(self):
with connection.cursor() as cursor:
indexes = connection.introspection.get_indexes(cursor, Article._meta.db_table)
+ if connection.features.can_introspect_index_type:
+ index_type = indexes['reporter_id'].pop('type', None)
+ self.assertIsNotNone(index_type)
+ if connection.vendor == 'postgresql':
+ self.assertEqual(index_type, 'btree')
self.assertEqual(indexes['reporter_id'], {'unique': False, 'primary_key': False})
def test_get_indexes_multicol(self):