Code

Ticket #18082: 18082.diff

File 18082.diff, 4.0 KB (added by akaariai, 2 years ago)
Line 
1diff --git a/django/db/backends/oracle/introspection.py b/django/db/backends/oracle/introspection.py
2index b8a8b2e..8db3e7d 100644
3--- a/django/db/backends/oracle/introspection.py
4+++ b/django/db/backends/oracle/introspection.py
5@@ -72,14 +72,14 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
6     FROM   user_constraints, USER_CONS_COLUMNS ca, USER_CONS_COLUMNS cb,
7            user_tab_cols ta, user_tab_cols tb
8     WHERE  user_constraints.table_name = %s AND
9-           ta.table_name = %s AND
10+           ta.table_name = user_constraints.table_name AND
11            ta.column_name = ca.column_name AND
12-           ca.table_name = %s AND
13+           ca.table_name = ta.table_name AND
14            user_constraints.constraint_name = ca.constraint_name AND
15            user_constraints.r_constraint_name = cb.constraint_name AND
16            cb.table_name = tb.table_name AND
17            cb.column_name = tb.column_name AND
18-           ca.position = cb.position""", [table_name, table_name, table_name])
19+           ca.position = cb.position""", [table_name])
20 
21         relations = {}
22         for row in cursor.fetchall():
23@@ -93,30 +93,37 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
24             {'primary_key': boolean representing whether it's the primary key,
25              'unique': boolean representing whether it's a unique index}
26         """
27-        # This query retrieves each index on the given table, including the
28-        # first associated field name
29-        # "We were in the nick of time; you were in great peril!"
30+        # A column can be a part of multiple indexes. Our introspection
31+        # logic ends at "if it is part of any unique index then it is unique".
32+        # This can naturally be wrong - maybe it is part of a multicolumn
33+        # unique index.
34+        #
35+        # The below SQL uses GROUP BY plus MAX to check if the index is part
36+        # of any UNIQUE index.
37         sql = """\
38-SELECT LOWER(all_tab_cols.column_name) AS column_name,
39-       CASE user_constraints.constraint_type
40-           WHEN 'P' THEN 1 ELSE 0
41-       END AS is_primary_key,
42-       CASE user_indexes.uniqueness
43-           WHEN 'UNIQUE' THEN 1 ELSE 0
44-       END AS is_unique
45-FROM   all_tab_cols, user_cons_columns, user_constraints, user_ind_columns, user_indexes
46-WHERE  all_tab_cols.column_name = user_cons_columns.column_name (+)
47-  AND  all_tab_cols.table_name = user_cons_columns.table_name (+)
48-  AND  user_cons_columns.constraint_name = user_constraints.constraint_name (+)
49-  AND  user_constraints.constraint_type (+) = 'P'
50-  AND  user_ind_columns.column_name (+) = all_tab_cols.column_name
51-  AND  user_ind_columns.table_name (+) = all_tab_cols.table_name
52-  AND  user_indexes.uniqueness (+) = 'UNIQUE'
53-  AND  user_indexes.index_name (+) = user_ind_columns.index_name
54-  AND  all_tab_cols.table_name = UPPER(%s)
55+SELECT column_name, MAX(is_primary_key) as is_primary_key,
56+       MAX(is_unique) as is_unique
57+  FROM (
58+    SELECT LOWER(user_ind_columns.column_name) AS column_name,
59+           CASE user_constraints.constraint_type
60+               WHEN 'P' THEN 1 ELSE 0
61+           END AS is_primary_key,
62+           CASE user_indexes.uniqueness
63+               WHEN 'UNIQUE' THEN 1 ELSE 0
64+           END AS is_unique
65+    FROM   user_constraints, user_ind_columns, user_indexes
66+    WHERE  user_constraints.constraint_type (+) = 'P'
67+      AND  user_constraints.index_name (+) = user_ind_columns.index_name
68+      AND  user_indexes.uniqueness (+) = 'UNIQUE'
69+      AND  user_indexes.index_name (+) = user_ind_columns.index_name
70+      AND  user_ind_columns.table_name = UPPER(%s)
71+      AND  user_ind_columns.column_position = 1
72+     )
73+ GROUP BY column_name
74 """
75         cursor.execute(sql, [table_name])
76         indexes = {}
77         for row in cursor.fetchall():
78-            indexes[row[0]] = {'primary_key': row[1], 'unique': row[2]}
79+            indexes[row[0]] = {'primary_key': bool(row[1]),
80+                               'unique': bool(row[2])}
81         return indexes