diff --git a/oslo_db/sqlalchemy/engines.py b/oslo_db/sqlalchemy/engines.py index 0e19c183..de3719ac 100644 --- a/oslo_db/sqlalchemy/engines.py +++ b/oslo_db/sqlalchemy/engines.py @@ -69,7 +69,7 @@ def _connect_ping_listener(connection, branch): connection.should_close_with_result = False try: # run a SELECT 1. use a core select() so that - # any details like that needed by Oracle, DB2 etc. are handled. + # any details like that needed by the backend are handled. connection.scalar(select([1])) except exception.DBConnectionError: # catch DBConnectionError, which is raised by the filter diff --git a/oslo_db/sqlalchemy/exc_filters.py b/oslo_db/sqlalchemy/exc_filters.py index 2b3ce2cb..e5789875 100644 --- a/oslo_db/sqlalchemy/exc_filters.py +++ b/oslo_db/sqlalchemy/exc_filters.py @@ -67,29 +67,25 @@ def filters(dbname, exception_type, regex): r"^.*\b1213\b.*Deadlock: wsrep aborted.*") @filters("postgresql", sqla_exc.OperationalError, r"^.*deadlock detected.*") @filters("postgresql", sqla_exc.DBAPIError, r"^.*deadlock detected.*") -@filters("ibm_db_sa", sqla_exc.DBAPIError, r"^.*SQL0911N.*") def _deadlock_error(operational_error, match, engine_name, is_disconnect): """Filter for MySQL or Postgresql deadlock error. NOTE(comstud): In current versions of DB backends, Deadlock violation messages follow the structure: - mysql+mysqldb: - (OperationalError) (1213, 'Deadlock found when trying to get lock; try ' - 'restarting transaction') + mysql+mysqldb:: - mysql+mysqlconnector: - (InternalError) 1213 (40001): Deadlock found when trying to get lock; try - restarting transaction + (OperationalError) (1213, 'Deadlock found when trying to get lock; ' + 'try restarting transaction') - postgresql: - (TransactionRollbackError) deadlock detected + mysql+mysqlconnector:: + (InternalError) 1213 (40001): Deadlock found when trying to get lock; + try restarting transaction - ibm_db_sa: - SQL0911N The current transaction has been rolled back because of a - deadlock or timeout + postgresql:: + (TransactionRollbackError) deadlock detected """ raise exception.DBDeadlock(operational_error) @@ -137,9 +133,6 @@ def _default_dupe_key_error(integrity_error, match, engine_name, key 'c1' N columns - (IntegrityError) 1062 (23000): Duplicate entry 'values joined with -' for key 'name_of_our_constraint' - - - """ columns = match.group('columns') @@ -184,7 +177,6 @@ def _sqlite_dupe_key_error(integrity_error, match, engine_name, is_disconnect): sqlite since 3.8.2: (IntegrityError) PRIMARY KEY must be unique - """ columns = [] # NOTE(ochuprykov): We can get here by last filter in which there are no @@ -321,24 +313,6 @@ def _check_database_non_existing( raise exception.DBNonExistentDatabase(database, error) -@filters("ibm_db_sa", sqla_exc.IntegrityError, r"^.*SQL0803N.*$") -def _db2_dupe_key_error(integrity_error, match, engine_name, is_disconnect): - """Filter for DB2 duplicate key errors. - - N columns - (IntegrityError) SQL0803N One or more values in the INSERT - statement, UPDATE statement, or foreign key update caused by a - DELETE statement are not valid because the primary key, unique - constraint or unique index identified by "2" constrains table - "NOVA.KEY_PAIRS" from having duplicate values for the index - key. - - """ - - # NOTE(mriedem): The ibm_db_sa integrity error message doesn't provide the - # columns so we have to omit that from the DBDuplicateEntry error. - raise exception.DBDuplicateEntry([], integrity_error) - - @filters("mysql", sqla_exc.DBAPIError, r".*\b1146\b") def _raise_mysql_table_doesnt_exist_asis( error, match, engine_name, is_disconnect): @@ -400,7 +374,6 @@ def _raise_operational_errors_directly_filter(operational_error, @filters("mysql", sqla_exc.InternalError, r".*\(.*(?:1927)") # noqa @filters("mysql", sqla_exc.InternalError, r".*Packet sequence number wrong") # noqa @filters("postgresql", sqla_exc.OperationalError, r".*could not connect to server") # noqa -@filters("ibm_db_sa", sqla_exc.OperationalError, r".*(?:30081)") def _is_db_connection_error(operational_error, match, engine_name, is_disconnect): """Detect the exception as indicating a recoverable error on connect.""" diff --git a/oslo_db/sqlalchemy/provision.py b/oslo_db/sqlalchemy/provision.py index 5addab45..199cba2f 100644 --- a/oslo_db/sqlalchemy/provision.py +++ b/oslo_db/sqlalchemy/provision.py @@ -263,7 +263,7 @@ class Backend(object): eng = sqlalchemy.create_engine(url) except ImportError as i_e: # SQLAlchemy performs an "import" of the DBAPI module - # within create_engine(). So if ibm_db_sa, cx_oracle etc. + # within create_engine(). So if mysql etc. # isn't installed, we get an ImportError here. LOG.info( "The %(dbapi)s backend is unavailable: %(err)s", diff --git a/oslo_db/tests/sqlalchemy/test_exc_filters.py b/oslo_db/tests/sqlalchemy/test_exc_filters.py index 677516d1..532c9497 100644 --- a/oslo_db/tests/sqlalchemy/test_exc_filters.py +++ b/oslo_db/tests/sqlalchemy/test_exc_filters.py @@ -881,28 +881,6 @@ class TestDuplicate(TestsExceptionFilter): exception.DBError ) - def test_ibm_db_sa(self): - self._run_dupe_constraint_test( - 'ibm_db_sa', - 'SQL0803N One or more values in the INSERT statement, UPDATE ' - 'statement, or foreign key update caused by a DELETE statement are' - ' not valid because the primary key, unique constraint or unique ' - 'index identified by "2" constrains table "NOVA.KEY_PAIRS" from ' - 'having duplicate values for the index key.', - expected_columns=[] - ) - - def test_ibm_db_sa_notadupe(self): - self._not_dupe_constraint_test( - 'ibm_db_sa', - 'ALTER TABLE instance_types ADD CONSTRAINT ' - 'uniq_name_x_deleted UNIQUE (name, deleted)', - 'SQL0542N The column named "NAME" cannot be a column of a ' - 'primary key or unique key constraint because it can contain null ' - 'values.', - exception.DBError - ) - class TestDeadlock(TestsExceptionFilter): statement = ('SELECT quota_usages.created_at AS ' @@ -1004,25 +982,6 @@ class TestDeadlock(TestsExceptionFilter): orig_exception_cls=self.TransactionRollbackError ) - def test_ibm_db_sa_deadlock(self): - self._run_deadlock_detect_test( - "ibm_db_sa", - "SQL0911N The current transaction has been " - "rolled back because of a deadlock or timeout", - # use the lowest class b.c. I don't know what actual error - # class DB2's driver would raise for this - orig_exception_cls=self.Error - ) - - def test_ibm_db_sa_not_deadlock(self): - self._not_deadlock_test( - "ibm_db_sa", - "SQL01234B Some other error.", - exception.DBError, - "Error", - orig_exception_cls=self.Error - ) - class TestDataError(TestsExceptionFilter): def _run_bad_data_test(self, dialect_name, message, error_class): @@ -1256,21 +1215,6 @@ class TestDBDisconnected(TestsExceptionFilter): is_disconnect=False ) - def test_db2_ping_listener_disconnected(self): - self._test_ping_listener_disconnected( - "ibm_db_sa", - self.OperationalError( - 'SQL30081N: DB2 Server connection is no longer active') - ) - - def test_db2_ping_listener_disconnected_regex_only(self): - self._test_ping_listener_disconnected( - "ibm_db_sa", - self.OperationalError( - 'SQL30081N: DB2 Server connection is no longer active'), - is_disconnect=False - ) - def test_postgresql_ping_listener_disconnected(self): self._test_ping_listener_disconnected( "postgresql", @@ -1355,24 +1299,6 @@ class TestDBConnectRetry(TestsExceptionFilter): 3, 2 ) - def test_db2_error_positive(self): - conn = self._run_test( - "ibm_db_sa", - self.OperationalError("blah blah -30081 blah blah"), - 2, -1 - ) - # conn is good - self.assertEqual(1, conn.scalar(sqla.select([1]))) - - def test_db2_error_negative(self): - self.assertRaises( - sqla.exc.OperationalError, - self._run_test, - "ibm_db_sa", - self.OperationalError("blah blah -39981 blah blah"), - 2, 3 - ) - class TestDBConnectPingWrapping(TestsExceptionFilter): diff --git a/oslo_db/tests/sqlalchemy/test_sqlalchemy.py b/oslo_db/tests/sqlalchemy/test_sqlalchemy.py index 2dd863ae..cd30f15c 100644 --- a/oslo_db/tests/sqlalchemy/test_sqlalchemy.py +++ b/oslo_db/tests/sqlalchemy/test_sqlalchemy.py @@ -202,22 +202,6 @@ class ProgrammingError(Exception): pass -class FakeDB2Engine(object): - - class Dialect(object): - - def is_disconnect(self, e, *args): - expected_error = ('SQL30081N: DB2 Server connection is no longer ' - 'active') - return (str(e) == expected_error) - - dialect = Dialect() - name = 'ibm_db_sa' - - def dispose(self): - pass - - class QueryParamTest(test_base.DbTestCase): def _fixture(self): from sqlalchemy import create_engine diff --git a/oslo_db/tests/sqlalchemy/test_utils.py b/oslo_db/tests/sqlalchemy/test_utils.py index 50f4af11..99238566 100644 --- a/oslo_db/tests/sqlalchemy/test_utils.py +++ b/oslo_db/tests/sqlalchemy/test_utils.py @@ -20,7 +20,7 @@ import fixtures from oslotest import base as test_base import sqlalchemy from sqlalchemy.dialects import mysql -from sqlalchemy import Boolean, Index, Integer, DateTime, String, SmallInteger +from sqlalchemy import Boolean, Index, Integer, DateTime, String from sqlalchemy import CheckConstraint from sqlalchemy import MetaData, Table, Column from sqlalchemy import ForeignKey, ForeignKeyConstraint @@ -847,8 +847,7 @@ class TestMigrationUtils(db_test_base._DbTestCase): self.assertIsInstance(table.c.deleted.type, Integer) def test_change_deleted_column_type_to_boolean(self): - expected_types = {'mysql': mysql.TINYINT, - 'ibm_db_sa': SmallInteger} + expected_types = {'mysql': mysql.TINYINT} table_name = 'abc' table = Table(table_name, self.meta, Column('id', Integer, primary_key=True), @@ -862,8 +861,7 @@ class TestMigrationUtils(db_test_base._DbTestCase): expected_types.get(self.engine.name, Boolean)) def test_change_deleted_column_type_to_boolean_with_fc(self): - expected_types = {'mysql': mysql.TINYINT, - 'ibm_db_sa': SmallInteger} + expected_types = {'mysql': mysql.TINYINT} table_name_1 = 'abc' table_name_2 = 'bcd' @@ -1605,7 +1603,6 @@ class TestDialectFunctionDispatcher(test_base.BaseTestCase): dispatcher("postgresql+pyodbc://", 1) dispatcher("mysql+pymysql://", 2) - dispatcher("ibm_db_sa+db2://", 3) dispatcher("postgresql+psycopg2://", 4) dispatcher("postgresql://", 5) @@ -1620,7 +1617,6 @@ class TestDialectFunctionDispatcher(test_base.BaseTestCase): mock.call.mysql_pymysql('mysql+pymysql://', 2), mock.call.mysql('mysql+pymysql://', 2), mock.call.default('mysql+pymysql://', 2), - mock.call.default('ibm_db_sa+db2://', 3), mock.call.postgresql_psycopg2('postgresql+psycopg2://', 4), mock.call.postgresql('postgresql+psycopg2://', 4), mock.call.default('postgresql+psycopg2://', 4), diff --git a/releasenotes/notes/drop-db2-support-6e70fe42268d2238.yaml b/releasenotes/notes/drop-db2-support-6e70fe42268d2238.yaml new file mode 100644 index 00000000..be32c3b1 --- /dev/null +++ b/releasenotes/notes/drop-db2-support-6e70fe42268d2238.yaml @@ -0,0 +1,5 @@ +--- +upgrade: + - | + Checks specific to the DB2 database have been removed. This database + has not been supported by any OpenStack project for many years.