You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

features.py 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import operator
  2. from django.db.backends.base.features import BaseDatabaseFeatures
  3. from django.utils.functional import cached_property
  4. class DatabaseFeatures(BaseDatabaseFeatures):
  5. empty_fetchmany_value = ()
  6. update_can_self_select = False
  7. allows_group_by_pk = True
  8. related_fields_match_type = True
  9. # MySQL doesn't support sliced subqueries with IN/ALL/ANY/SOME.
  10. allow_sliced_subqueries_with_in = False
  11. has_select_for_update = True
  12. supports_forward_references = False
  13. supports_regex_backreferencing = False
  14. supports_date_lookup_using_string = False
  15. can_introspect_autofield = True
  16. can_introspect_binary_field = False
  17. can_introspect_duration_field = False
  18. can_introspect_small_integer_field = True
  19. can_introspect_positive_integer_field = True
  20. introspected_boolean_field_type = 'IntegerField'
  21. supports_index_column_ordering = False
  22. supports_timezones = False
  23. requires_explicit_null_ordering_when_grouping = True
  24. allows_auto_pk_0 = False
  25. can_release_savepoints = True
  26. atomic_transactions = False
  27. supports_column_check_constraints = False
  28. supports_table_check_constraints = False
  29. can_clone_databases = True
  30. supports_temporal_subtraction = True
  31. supports_select_intersection = False
  32. supports_select_difference = False
  33. supports_slicing_ordering_in_compound = True
  34. supports_index_on_text_field = False
  35. has_case_insensitive_like = False
  36. create_test_procedure_without_params_sql = """
  37. CREATE PROCEDURE test_procedure ()
  38. BEGIN
  39. DECLARE V_I INTEGER;
  40. SET V_I = 1;
  41. END;
  42. """
  43. create_test_procedure_with_int_param_sql = """
  44. CREATE PROCEDURE test_procedure (P_I INTEGER)
  45. BEGIN
  46. DECLARE V_I INTEGER;
  47. SET V_I = P_I;
  48. END;
  49. """
  50. db_functions_convert_bytes_to_str = True
  51. # Alias MySQL's TRADITIONAL to TEXT for consistency with other backends.
  52. supported_explain_formats = {'JSON', 'TEXT', 'TRADITIONAL'}
  53. # Neither MySQL nor MariaDB support partial indexes.
  54. supports_partial_indexes = False
  55. @cached_property
  56. def _mysql_storage_engine(self):
  57. "Internal method used in Django tests. Don't rely on this from your code"
  58. with self.connection.cursor() as cursor:
  59. cursor.execute("SELECT ENGINE FROM INFORMATION_SCHEMA.ENGINES WHERE SUPPORT = 'DEFAULT'")
  60. result = cursor.fetchone()
  61. return result[0]
  62. @cached_property
  63. def can_introspect_foreign_keys(self):
  64. "Confirm support for introspected foreign keys"
  65. return self._mysql_storage_engine != 'MyISAM'
  66. @cached_property
  67. def has_zoneinfo_database(self):
  68. # Test if the time zone definitions are installed.
  69. with self.connection.cursor() as cursor:
  70. cursor.execute("SELECT 1 FROM mysql.time_zone LIMIT 1")
  71. return cursor.fetchone() is not None
  72. @cached_property
  73. def is_sql_auto_is_null_enabled(self):
  74. with self.connection.cursor() as cursor:
  75. cursor.execute('SELECT @@SQL_AUTO_IS_NULL')
  76. result = cursor.fetchone()
  77. return result and result[0] == 1
  78. @cached_property
  79. def supports_over_clause(self):
  80. if self.connection.mysql_is_mariadb:
  81. return self.connection.mysql_version >= (10, 2)
  82. return self.connection.mysql_version >= (8, 0, 2)
  83. @cached_property
  84. def has_select_for_update_skip_locked(self):
  85. return not self.connection.mysql_is_mariadb and self.connection.mysql_version >= (8, 0, 1)
  86. has_select_for_update_nowait = property(operator.attrgetter('has_select_for_update_skip_locked'))
  87. @cached_property
  88. def needs_explain_extended(self):
  89. # EXTENDED is deprecated (and not required) in MySQL 5.7.
  90. return not self.connection.mysql_is_mariadb and self.connection.mysql_version < (5, 7)
  91. @cached_property
  92. def supports_transactions(self):
  93. """
  94. All storage engines except MyISAM support transactions.
  95. """
  96. return self._mysql_storage_engine != 'MyISAM'
  97. @cached_property
  98. def ignores_table_name_case(self):
  99. with self.connection.cursor() as cursor:
  100. cursor.execute('SELECT @@LOWER_CASE_TABLE_NAMES')
  101. result = cursor.fetchone()
  102. return result and result[0] != 0
  103. @cached_property
  104. def supports_default_in_lead_lag(self):
  105. # To be added in https://jira.mariadb.org/browse/MDEV-12981.
  106. return not self.connection.mysql_is_mariadb