@@ -1173,6 +1173,87 @@ def test_percona_migration(monkeypatch):
11731173 binlog_replicator_runner .stop ()
11741174
11751175
1176+ def test_add_column_first_after_and_drop_column (monkeypatch ):
1177+ monkeypatch .setattr (DbReplicator , 'INITIAL_REPLICATION_BATCH_SIZE' , 1 )
1178+
1179+ cfg = config .Settings ()
1180+ cfg .load (CONFIG_FILE )
1181+
1182+ mysql = mysql_api .MySQLApi (
1183+ database = None ,
1184+ mysql_settings = cfg .mysql ,
1185+ )
1186+
1187+ ch = clickhouse_api .ClickhouseApi (
1188+ database = TEST_DB_NAME ,
1189+ clickhouse_settings = cfg .clickhouse ,
1190+ )
1191+
1192+ prepare_env (cfg , mysql , ch )
1193+
1194+ mysql .execute (f'''
1195+ CREATE TABLE { TEST_TABLE_NAME } (
1196+ `id` int NOT NULL,
1197+ PRIMARY KEY (`id`));
1198+ ''' )
1199+
1200+ mysql .execute (
1201+ f"INSERT INTO { TEST_TABLE_NAME } (id) VALUES (42)" ,
1202+ commit = True ,
1203+ )
1204+
1205+ binlog_replicator_runner = BinlogReplicatorRunner ()
1206+ binlog_replicator_runner .run ()
1207+ db_replicator_runner = DbReplicatorRunner (TEST_DB_NAME )
1208+ db_replicator_runner .run ()
1209+
1210+ assert_wait (lambda : TEST_DB_NAME in ch .get_databases ())
1211+
1212+ ch .execute_command (f'USE { TEST_DB_NAME } ' )
1213+
1214+ assert_wait (lambda : TEST_TABLE_NAME in ch .get_tables ())
1215+ assert_wait (lambda : len (ch .select (TEST_TABLE_NAME )) == 1 )
1216+
1217+ # Test adding a column as the new first column, after another column, and dropping a column
1218+ # These all move the primary key column to a different index and test the table structure is
1219+ # updated correctly.
1220+
1221+ # Test add column first
1222+ mysql .execute (
1223+ f"ALTER TABLE { TEST_TABLE_NAME } ADD COLUMN c1 INT FIRST" )
1224+ mysql .execute (
1225+ f"INSERT INTO { TEST_TABLE_NAME } (id, c1) VALUES (43, 11)" ,
1226+ commit = True ,
1227+ )
1228+ assert_wait (lambda : len (ch .select (TEST_TABLE_NAME , where = "id=43" )) == 1 )
1229+ assert_wait (lambda : ch .select (TEST_TABLE_NAME , where = "id=43" )[0 ]['c1' ] == 11 )
1230+
1231+ # Test add column after
1232+ mysql .execute (
1233+ f"ALTER TABLE { TEST_TABLE_NAME } ADD COLUMN c2 INT AFTER c1" )
1234+ mysql .execute (
1235+ f"INSERT INTO { TEST_TABLE_NAME } (id, c1, c2) VALUES (44, 111, 222)" ,
1236+ commit = True ,
1237+ )
1238+ assert_wait (lambda : len (ch .select (TEST_TABLE_NAME , where = "id=44" )) == 1 )
1239+ assert_wait (lambda : ch .select (TEST_TABLE_NAME , where = "id=44" )[0 ]['c1' ] == 111 )
1240+ assert_wait (lambda : ch .select (TEST_TABLE_NAME , where = "id=44" )[0 ]['c2' ] == 222 )
1241+
1242+ # Test drop column
1243+ mysql .execute (
1244+ f"ALTER TABLE { TEST_TABLE_NAME } DROP COLUMN c2" )
1245+ mysql .execute (
1246+ f"INSERT INTO { TEST_TABLE_NAME } (id, c1) VALUES (45, 1111)" ,
1247+ commit = True ,
1248+ )
1249+ assert_wait (lambda : len (ch .select (TEST_TABLE_NAME , where = "id=45" )) == 1 )
1250+ assert_wait (lambda : ch .select (TEST_TABLE_NAME , where = "id=45" )[0 ]['c1' ] == 1111 )
1251+ assert_wait (lambda : ch .select (TEST_TABLE_NAME , where = "id=45" )[0 ].get ('c2' ) is None )
1252+
1253+ db_replicator_runner .stop ()
1254+ binlog_replicator_runner .stop ()
1255+
1256+
11761257def test_parse_mysql_table_structure ():
11771258 query = "CREATE TABLE IF NOT EXISTS user_preferences_portal (\n \t \t \t id char(36) NOT NULL,\n \t \t \t category varchar(50) DEFAULT NULL,\n \t \t \t deleted tinyint(1) DEFAULT 0,\n \t \t \t date_entered datetime DEFAULT NULL,\n \t \t \t date_modified datetime DEFAULT NULL,\n \t \t \t assigned_user_id char(36) DEFAULT NULL,\n \t \t \t contents longtext DEFAULT NULL\n \t \t ) ENGINE=InnoDB DEFAULT CHARSET=utf8"
11781259
0 commit comments