mirror of
https://github.com/django/django.git
synced 2025-03-12 02:12:38 +00:00
Fixed #34671 -- Fixed collation introspection for views and materialized views on Oracle.
Thanks Philipp Maino for the report.
This commit is contained in:
parent
c4a09499aa
commit
a6d30f5012
@ -110,6 +110,31 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
|
|||||||
Return a description of the table with the DB-API cursor.description
|
Return a description of the table with the DB-API cursor.description
|
||||||
interface.
|
interface.
|
||||||
"""
|
"""
|
||||||
|
# A default collation for the given table/view/materialized view.
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
SELECT user_tables.default_collation
|
||||||
|
FROM user_tables
|
||||||
|
WHERE
|
||||||
|
user_tables.table_name = UPPER(%s) AND
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM user_mviews
|
||||||
|
WHERE user_mviews.mview_name = user_tables.table_name
|
||||||
|
)
|
||||||
|
UNION ALL
|
||||||
|
SELECT user_views.default_collation
|
||||||
|
FROM user_views
|
||||||
|
WHERE user_views.view_name = UPPER(%s)
|
||||||
|
UNION ALL
|
||||||
|
SELECT user_mviews.default_collation
|
||||||
|
FROM user_mviews
|
||||||
|
WHERE user_mviews.mview_name = UPPER(%s)
|
||||||
|
""",
|
||||||
|
[table_name, table_name, table_name],
|
||||||
|
)
|
||||||
|
row = cursor.fetchone()
|
||||||
|
default_table_collation = row[0] if row else ""
|
||||||
# user_tab_columns gives data default for columns
|
# user_tab_columns gives data default for columns
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
"""
|
"""
|
||||||
@ -117,7 +142,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
|
|||||||
user_tab_cols.column_name,
|
user_tab_cols.column_name,
|
||||||
user_tab_cols.data_default,
|
user_tab_cols.data_default,
|
||||||
CASE
|
CASE
|
||||||
WHEN user_tab_cols.collation = user_tables.default_collation
|
WHEN user_tab_cols.collation = %s
|
||||||
THEN NULL
|
THEN NULL
|
||||||
ELSE user_tab_cols.collation
|
ELSE user_tab_cols.collation
|
||||||
END collation,
|
END collation,
|
||||||
@ -143,15 +168,13 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
|
|||||||
END as is_json,
|
END as is_json,
|
||||||
user_col_comments.comments as col_comment
|
user_col_comments.comments as col_comment
|
||||||
FROM user_tab_cols
|
FROM user_tab_cols
|
||||||
LEFT OUTER JOIN
|
|
||||||
user_tables ON user_tables.table_name = user_tab_cols.table_name
|
|
||||||
LEFT OUTER JOIN
|
LEFT OUTER JOIN
|
||||||
user_col_comments ON
|
user_col_comments ON
|
||||||
user_col_comments.column_name = user_tab_cols.column_name AND
|
user_col_comments.column_name = user_tab_cols.column_name AND
|
||||||
user_col_comments.table_name = user_tab_cols.table_name
|
user_col_comments.table_name = user_tab_cols.table_name
|
||||||
WHERE user_tab_cols.table_name = UPPER(%s)
|
WHERE user_tab_cols.table_name = UPPER(%s)
|
||||||
""",
|
""",
|
||||||
[table_name],
|
[default_table_collation, table_name],
|
||||||
)
|
)
|
||||||
field_map = {
|
field_map = {
|
||||||
column: (
|
column: (
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
from django.test import TransactionTestCase
|
from django.test import TransactionTestCase, skipUnlessDBFeature
|
||||||
|
|
||||||
from ..models import Square
|
from ..models import Person, Square
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(connection.vendor == "oracle", "Oracle tests")
|
@unittest.skipUnless(connection.vendor == "oracle", "Oracle tests")
|
||||||
@ -33,3 +33,54 @@ class DatabaseSequenceTests(TransactionTestCase):
|
|||||||
# Recreate model, because adding identity is impossible.
|
# Recreate model, because adding identity is impossible.
|
||||||
editor.delete_model(Square)
|
editor.delete_model(Square)
|
||||||
editor.create_model(Square)
|
editor.create_model(Square)
|
||||||
|
|
||||||
|
@skipUnlessDBFeature("supports_collation_on_charfield")
|
||||||
|
def test_get_table_description_view_default_collation(self):
|
||||||
|
person_table = connection.introspection.identifier_converter(
|
||||||
|
Person._meta.db_table
|
||||||
|
)
|
||||||
|
first_name_column = connection.ops.quote_name(
|
||||||
|
Person._meta.get_field("first_name").column
|
||||||
|
)
|
||||||
|
person_view = connection.introspection.identifier_converter("TEST_PERSON_VIEW")
|
||||||
|
with connection.cursor() as cursor:
|
||||||
|
cursor.execute(
|
||||||
|
f"CREATE VIEW {person_view} "
|
||||||
|
f"AS SELECT {first_name_column} FROM {person_table}"
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
columns = connection.introspection.get_table_description(
|
||||||
|
cursor, person_view
|
||||||
|
)
|
||||||
|
self.assertEqual(len(columns), 1)
|
||||||
|
self.assertIsNone(columns[0].collation)
|
||||||
|
finally:
|
||||||
|
cursor.execute(f"DROP VIEW {person_view}")
|
||||||
|
|
||||||
|
@skipUnlessDBFeature("supports_collation_on_charfield")
|
||||||
|
def test_get_table_description_materialized_view_non_default_collation(self):
|
||||||
|
person_table = connection.introspection.identifier_converter(
|
||||||
|
Person._meta.db_table
|
||||||
|
)
|
||||||
|
first_name_column = connection.ops.quote_name(
|
||||||
|
Person._meta.get_field("first_name").column
|
||||||
|
)
|
||||||
|
person_mview = connection.introspection.identifier_converter(
|
||||||
|
"TEST_PERSON_MVIEW"
|
||||||
|
)
|
||||||
|
collation = connection.features.test_collations.get("ci")
|
||||||
|
with connection.cursor() as cursor:
|
||||||
|
cursor.execute(
|
||||||
|
f"CREATE MATERIALIZED VIEW {person_mview} "
|
||||||
|
f"DEFAULT COLLATION {collation} "
|
||||||
|
f"AS SELECT {first_name_column} FROM {person_table}"
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
columns = connection.introspection.get_table_description(
|
||||||
|
cursor, person_mview
|
||||||
|
)
|
||||||
|
self.assertEqual(len(columns), 1)
|
||||||
|
self.assertIsNotNone(columns[0].collation)
|
||||||
|
self.assertNotEqual(columns[0].collation, collation)
|
||||||
|
finally:
|
||||||
|
cursor.execute(f"DROP MATERIALIZED VIEW {person_mview}")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user