Drop support for sqlite<3.22 as well

This commit is contained in:
Richard van der Hoff 2021-04-08 13:45:19 +01:00
parent abade34633
commit 3ada9b4264
6 changed files with 14 additions and 92 deletions

View file

@ -1 +1 @@
Synapse now requires Python 3.6 or later and Postgres 9.6 or later. Synapse now requires Python 3.6 or later. It also requires Postgres 9.6 or later or SQLite 3.22 or later.

View file

@ -2060,68 +2060,20 @@ KV = TypeVar("KV")
def make_tuple_comparison_clause( def make_tuple_comparison_clause(
database_engine: BaseDatabaseEngine, keys: List[Tuple[str, KV]] _database_engine: BaseDatabaseEngine, keys: List[Tuple[str, KV]]
) -> Tuple[str, List[KV]]: ) -> Tuple[str, List[KV]]:
"""Returns a tuple comparison SQL clause """Returns a tuple comparison SQL clause
Depending what the SQL engine supports, builds a SQL clause that looks like either Builds a SQL clause that looks like "(a, b) > (?, ?)"
"(a, b) > (?, ?)", or "(a > ?) OR (a == ? AND b > ?)".
Args: Args:
database_engine _database_engine
keys: A set of (column, value) pairs to be compared. keys: A set of (column, value) pairs to be compared.
Returns: Returns:
A tuple of SQL query and the args A tuple of SQL query and the args
""" """
if database_engine.supports_tuple_comparison: return (
return ( "(%s) > (%s)" % (",".join(k[0] for k in keys), ",".join("?" for _ in keys)),
"(%s) > (%s)" % (",".join(k[0] for k in keys), ",".join("?" for _ in keys)), [k[1] for k in keys],
[k[1] for k in keys], )
)
# we want to build a clause
# (a > ?) OR
# (a == ? AND b > ?) OR
# (a == ? AND b == ? AND c > ?)
# ...
# (a == ? AND b == ? AND ... AND z > ?)
#
# or, equivalently:
#
# (a > ? OR (a == ? AND
# (b > ? OR (b == ? AND
# ...
# (y > ? OR (y == ? AND
# z > ?
# ))
# ...
# ))
# ))
#
# which itself is equivalent to (and apparently easier for the query optimiser):
#
# (a >= ? AND (a > ? OR
# (b >= ? AND (b > ? OR
# ...
# (y >= ? AND (y > ? OR
# z > ?
# ))
# ...
# ))
# ))
#
#
clause = ""
args = [] # type: List[KV]
for k, v in keys[:-1]:
clause = clause + "(%s >= ? AND (%s > ? OR " % (k, k)
args.extend([v, v])
(k, v) = keys[-1]
clause += "%s > ?" % (k,)
args.append(v)
clause += "))" * (len(keys) - 1)
return clause, args

View file

@ -42,14 +42,6 @@ class BaseDatabaseEngine(Generic[ConnectionType], metaclass=abc.ABCMeta):
""" """
... ...
@property
@abc.abstractmethod
def supports_tuple_comparison(self) -> bool:
"""
Do we support comparing tuples, i.e. `(a, b) > (c, d)`?
"""
...
@property @property
@abc.abstractmethod @abc.abstractmethod
def supports_using_any_list(self) -> bool: def supports_using_any_list(self) -> bool:

View file

@ -129,13 +129,6 @@ class PostgresEngine(BaseDatabaseEngine):
""" """
return True return True
@property
def supports_tuple_comparison(self):
"""
Do we support comparing tuples, i.e. `(a, b) > (c, d)`?
"""
return True
@property @property
def supports_using_any_list(self): def supports_using_any_list(self):
"""Do we support using `a = ANY(?)` and passing a list""" """Do we support using `a = ANY(?)` and passing a list"""

View file

@ -56,14 +56,6 @@ class Sqlite3Engine(BaseDatabaseEngine["sqlite3.Connection"]):
""" """
return self.module.sqlite_version_info >= (3, 24, 0) return self.module.sqlite_version_info >= (3, 24, 0)
@property
def supports_tuple_comparison(self):
"""
Do we support comparing tuples, i.e. `(a, b) > (c, d)`? This requires
SQLite 3.15+.
"""
return self.module.sqlite_version_info >= (3, 15, 0)
@property @property
def supports_using_any_list(self): def supports_using_any_list(self):
"""Do we support using `a = ANY(?)` and passing a list""" """Do we support using `a = ANY(?)` and passing a list"""
@ -72,8 +64,11 @@ class Sqlite3Engine(BaseDatabaseEngine["sqlite3.Connection"]):
def check_database(self, db_conn, allow_outdated_version: bool = False): def check_database(self, db_conn, allow_outdated_version: bool = False):
if not allow_outdated_version: if not allow_outdated_version:
version = self.module.sqlite_version_info version = self.module.sqlite_version_info
if version < (3, 11, 0): # Synapse is untested against older SQLite versions, and we don't want
raise RuntimeError("Synapse requires sqlite 3.11 or above.") # to let users upgrade to a version of Synapse with broken support for their
# sqlite version, because it risks leaving them with a half-upgraded db.
if version < (3, 22, 0):
raise RuntimeError("Synapse requires sqlite 3.22 or above.")
def check_new_database(self, txn): def check_new_database(self, txn):
"""Gets called when setting up a brand new database. This allows us to """Gets called when setting up a brand new database. This allows us to

View file

@ -36,17 +36,7 @@ def _stub_db_engine(**kwargs) -> BaseDatabaseEngine:
class TupleComparisonClauseTestCase(unittest.TestCase): class TupleComparisonClauseTestCase(unittest.TestCase):
def test_native_tuple_comparison(self): def test_native_tuple_comparison(self):
db_engine = _stub_db_engine(supports_tuple_comparison=True) db_engine = _stub_db_engine()
clause, args = make_tuple_comparison_clause(db_engine, [("a", 1), ("b", 2)]) clause, args = make_tuple_comparison_clause(db_engine, [("a", 1), ("b", 2)])
self.assertEqual(clause, "(a,b) > (?,?)") self.assertEqual(clause, "(a,b) > (?,?)")
self.assertEqual(args, [1, 2]) self.assertEqual(args, [1, 2])
def test_emulated_tuple_comparison(self):
db_engine = _stub_db_engine(supports_tuple_comparison=False)
clause, args = make_tuple_comparison_clause(
db_engine, [("a", 1), ("b", 2), ("c", 3)]
)
self.assertEqual(
clause, "(a >= ? AND (a > ? OR (b >= ? AND (b > ? OR c > ?))))"
)
self.assertEqual(args, [1, 1, 2, 2, 3])