Refs #27030 -- Added index type introspection on PostgreSQL.
This commit is contained in:
parent
72d541b61c
commit
2f19306a12
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue