mirror of https://github.com/django/django.git
Updated DatabaseFeatures.bare_select_suffix on Oracle 23c.
https://docs.oracle.com/en/database/oracle/oracle-database/23/nfcoa/application-development.html#GUID-4EB70EB9-4EE3-4FE2-99C4-86F7AAC60F12
This commit is contained in:
parent
a816efe238
commit
c72001644f
|
@ -37,7 +37,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
||||||
requires_literal_defaults = True
|
requires_literal_defaults = True
|
||||||
supports_default_keyword_in_bulk_insert = False
|
supports_default_keyword_in_bulk_insert = False
|
||||||
closed_cursor_error_class = InterfaceError
|
closed_cursor_error_class = InterfaceError
|
||||||
bare_select_suffix = " FROM DUAL"
|
|
||||||
# Select for update with limit can be achieved on Oracle, but not with the
|
# Select for update with limit can be achieved on Oracle, but not with the
|
||||||
# current backend.
|
# current backend.
|
||||||
supports_select_for_update_with_limit = False
|
supports_select_for_update_with_limit = False
|
||||||
|
@ -159,9 +158,10 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def supports_collation_on_charfield(self):
|
def supports_collation_on_charfield(self):
|
||||||
|
sql = "SELECT CAST('a' AS VARCHAR2(4001))" + self.bare_select_suffix
|
||||||
with self.connection.cursor() as cursor:
|
with self.connection.cursor() as cursor:
|
||||||
try:
|
try:
|
||||||
cursor.execute("SELECT CAST('a' AS VARCHAR2(4001)) FROM dual")
|
cursor.execute(sql)
|
||||||
except DatabaseError as e:
|
except DatabaseError as e:
|
||||||
if e.args[0].code == 910:
|
if e.args[0].code == 910:
|
||||||
return False
|
return False
|
||||||
|
@ -183,3 +183,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
||||||
@cached_property
|
@cached_property
|
||||||
def supports_aggregation_over_interval_types(self):
|
def supports_aggregation_over_interval_types(self):
|
||||||
return self.connection.oracle_version >= (23,)
|
return self.connection.oracle_version >= (23,)
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def bare_select_suffix(self):
|
||||||
|
return "" if self.connection.oracle_version >= (23,) else " FROM DUAL"
|
||||||
|
|
|
@ -54,7 +54,7 @@ BEGIN
|
||||||
SELECT NVL(last_number - cache_size, 0) INTO seq_value FROM user_sequences
|
SELECT NVL(last_number - cache_size, 0) INTO seq_value FROM user_sequences
|
||||||
WHERE sequence_name = seq_name;
|
WHERE sequence_name = seq_name;
|
||||||
WHILE table_value > seq_value LOOP
|
WHILE table_value > seq_value LOOP
|
||||||
EXECUTE IMMEDIATE 'SELECT "'||seq_name||'".nextval FROM DUAL'
|
EXECUTE IMMEDIATE 'SELECT "'||seq_name||'".nextval%(suffix)s'
|
||||||
INTO seq_value;
|
INTO seq_value;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END;
|
END;
|
||||||
|
@ -527,6 +527,7 @@ END;
|
||||||
"column": column,
|
"column": column,
|
||||||
"table_name": strip_quotes(table),
|
"table_name": strip_quotes(table),
|
||||||
"column_name": strip_quotes(column),
|
"column_name": strip_quotes(column),
|
||||||
|
"suffix": self.connection.features.bare_select_suffix,
|
||||||
}
|
}
|
||||||
sql.append(query)
|
sql.append(query)
|
||||||
return sql
|
return sql
|
||||||
|
@ -550,6 +551,7 @@ END;
|
||||||
"column": column,
|
"column": column,
|
||||||
"table_name": strip_quotes(table),
|
"table_name": strip_quotes(table),
|
||||||
"column_name": strip_quotes(column),
|
"column_name": strip_quotes(column),
|
||||||
|
"suffix": self.connection.features.bare_select_suffix,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
# Only one AutoField is allowed per model, so don't
|
# Only one AutoField is allowed per model, so don't
|
||||||
|
@ -683,7 +685,8 @@ END;
|
||||||
if not query:
|
if not query:
|
||||||
placeholder = "%s col_%s" % (placeholder, i)
|
placeholder = "%s col_%s" % (placeholder, i)
|
||||||
select.append(placeholder)
|
select.append(placeholder)
|
||||||
query.append("SELECT %s FROM DUAL" % ", ".join(select))
|
suffix = self.connection.features.bare_select_suffix
|
||||||
|
query.append(f"SELECT %s{suffix}" % ", ".join(select))
|
||||||
# Bulk insert to tables with Oracle identity columns causes Oracle to
|
# Bulk insert to tables with Oracle identity columns causes Oracle to
|
||||||
# add sequence.nextval to it. Sequence.nextval cannot be used with the
|
# add sequence.nextval to it. Sequence.nextval cannot be used with the
|
||||||
# UNION operator. To prevent incorrect SQL, move UNION to a subquery.
|
# UNION operator. To prevent incorrect SQL, move UNION to a subquery.
|
||||||
|
|
|
@ -261,13 +261,14 @@ class Reverse(Transform):
|
||||||
def as_oracle(self, compiler, connection, **extra_context):
|
def as_oracle(self, compiler, connection, **extra_context):
|
||||||
# REVERSE in Oracle is undocumented and doesn't support multi-byte
|
# REVERSE in Oracle is undocumented and doesn't support multi-byte
|
||||||
# strings. Use a special subquery instead.
|
# strings. Use a special subquery instead.
|
||||||
|
suffix = connection.features.bare_select_suffix
|
||||||
sql, params = super().as_sql(
|
sql, params = super().as_sql(
|
||||||
compiler,
|
compiler,
|
||||||
connection,
|
connection,
|
||||||
template=(
|
template=(
|
||||||
"(SELECT LISTAGG(s) WITHIN GROUP (ORDER BY n DESC) FROM "
|
"(SELECT LISTAGG(s) WITHIN GROUP (ORDER BY n DESC) FROM "
|
||||||
"(SELECT LEVEL n, SUBSTR(%(expressions)s, LEVEL, 1) s "
|
f"(SELECT LEVEL n, SUBSTR(%(expressions)s, LEVEL, 1) s{suffix} "
|
||||||
"FROM DUAL CONNECT BY LEVEL <= LENGTH(%(expressions)s)) "
|
"CONNECT BY LEVEL <= LENGTH(%(expressions)s)) "
|
||||||
"GROUP BY %(expressions)s)"
|
"GROUP BY %(expressions)s)"
|
||||||
),
|
),
|
||||||
**extra_context,
|
**extra_context,
|
||||||
|
|
|
@ -43,8 +43,9 @@ class Tests(TestCase):
|
||||||
An 'almost right' datetime works with configured NLS parameters
|
An 'almost right' datetime works with configured NLS parameters
|
||||||
(#18465).
|
(#18465).
|
||||||
"""
|
"""
|
||||||
|
suffix = connection.features.bare_select_suffix
|
||||||
with connection.cursor() as cursor:
|
with connection.cursor() as cursor:
|
||||||
query = "select 1 from dual where '1936-12-29 00:00' < sysdate"
|
query = f"SELECT 1{suffix} WHERE '1936-12-29 00:00' < SYSDATE"
|
||||||
# The query succeeds without errors - pre #18465 this
|
# The query succeeds without errors - pre #18465 this
|
||||||
# wasn't the case.
|
# wasn't the case.
|
||||||
cursor.execute(query)
|
cursor.execute(query)
|
||||||
|
|
Loading…
Reference in New Issue