Skip to content

Commit 288ea67

Browse files
committed
feat(tests): add MySQL indexes schema migration test and update index metadata query to exclude PRIMARY key
1 parent 88540ef commit 288ea67

File tree

3 files changed

+145
-1
lines changed

3 files changed

+145
-1
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# Schema Migration Test: MySQL Indexes (exclude PRIMARY)
2+
# Tests: indexes query excludes PRIMARY key from results and includes uniqueness info
3+
4+
env:
5+
SOURCE: mysql
6+
TARGET: postgres
7+
8+
steps:
9+
# Clean up target first
10+
- type: query
11+
connection: '{env.TARGET}'
12+
query: DROP TABLE IF EXISTS public.sm_mysql_indexes_fix CASCADE;
13+
14+
# Clean up source (disable FK checks for easier cleanup)
15+
- type: query
16+
connection: '{env.SOURCE}'
17+
query: |
18+
SET FOREIGN_KEY_CHECKS = 0;
19+
DROP TABLE IF EXISTS sm_mysql_indexes_fix;
20+
SET FOREIGN_KEY_CHECKS = 1;
21+
22+
# Create source table with PRIMARY key and secondary indexes
23+
- type: query
24+
connection: '{env.SOURCE}'
25+
query: |
26+
CREATE TABLE sm_mysql_indexes_fix (
27+
id INT AUTO_INCREMENT PRIMARY KEY,
28+
email VARCHAR(255) NOT NULL,
29+
name VARCHAR(100),
30+
status INT DEFAULT 1,
31+
UNIQUE INDEX idx_email (email),
32+
INDEX idx_name (name),
33+
INDEX idx_status (status)
34+
) ENGINE=InnoDB;
35+
INSERT INTO sm_mysql_indexes_fix (email, name, status) VALUES ('test@example.com', 'Test User', 1);
36+
37+
# Run replication with schema migration
38+
- replication:
39+
source: mysql
40+
target: postgres
41+
42+
env:
43+
SLING_SCHEMA_MIGRATION: primary_key,indexes
44+
45+
defaults:
46+
mode: full-refresh
47+
48+
streams:
49+
mysql.sm_mysql_indexes_fix:
50+
object: public.sm_mysql_indexes_fix
51+
52+
# Validate primary key was created
53+
- type: query
54+
connection: '{env.TARGET}'
55+
query: |
56+
SELECT count(*) as cnt
57+
FROM information_schema.table_constraints
58+
WHERE table_schema = 'public'
59+
AND table_name = 'sm_mysql_indexes_fix'
60+
AND constraint_type = 'PRIMARY KEY'
61+
into: pk_count
62+
63+
- type: log
64+
message: "Primary key constraints found: {store.pk_count[0].cnt}"
65+
66+
- type: check
67+
check: int_parse(store.pk_count[0].cnt) == 1
68+
message: "Expected 1 primary key constraint, got {store.pk_count[0].cnt}"
69+
70+
# Validate indexes (should NOT include PRIMARY in the result)
71+
# Should have 3 indexes: idx_email, idx_name, idx_status
72+
- type: query
73+
connection: '{env.TARGET}'
74+
query: |
75+
SELECT indexname
76+
FROM pg_indexes
77+
WHERE schemaname = 'public'
78+
AND tablename = 'sm_mysql_indexes_fix'
79+
AND indexname NOT LIKE '%pkey%'
80+
ORDER BY indexname
81+
into: index_result
82+
83+
- type: log
84+
message: "Indexes found (excluding PK): {store.index_result}"
85+
86+
- type: check
87+
check: length(store.index_result) == 3
88+
message: "Expected 3 non-PK indexes"
89+
90+
# Validate data migrated correctly
91+
- type: query
92+
connection: '{env.TARGET}'
93+
query: |
94+
SELECT count(*) as cnt FROM public.sm_mysql_indexes_fix
95+
into: data_count
96+
97+
- type: log
98+
message: "Migrated rows: {store.data_count[0].cnt}"
99+
100+
- type: check
101+
check: int_parse(store.data_count[0].cnt) == 1
102+
message: "Expected 1 row, got {store.data_count[0].cnt}"
103+
104+
# Validate unique index was created (idx_email should be unique)
105+
- type: query
106+
connection: '{env.TARGET}'
107+
query: |
108+
SELECT indexname, indisunique
109+
FROM pg_indexes i
110+
JOIN pg_class c ON c.relname = i.indexname
111+
JOIN pg_index idx ON idx.indexrelid = c.oid
112+
WHERE i.schemaname = 'public'
113+
AND i.tablename = 'sm_mysql_indexes_fix'
114+
AND i.indexname LIKE '%email%'
115+
into: unique_idx
116+
117+
- type: log
118+
message: "Unique index info: {store.unique_idx}"
119+
120+
# Clean up
121+
- type: query
122+
connection: '{env.SOURCE}'
123+
query: |
124+
SET FOREIGN_KEY_CHECKS = 0;
125+
DROP TABLE IF EXISTS sm_mysql_indexes_fix;
126+
SET FOREIGN_KEY_CHECKS = 1;
127+
128+
- type: query
129+
connection: '{env.TARGET}'
130+
query: DROP TABLE IF EXISTS public.sm_mysql_indexes_fix CASCADE;

cmd/sling/tests/suite.cli.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,4 +1834,15 @@
18341834
output_contains:
18351835
- 'Columns found: 6'
18361836
- 'Column names'
1837+
- 'execution succeeded'
1838+
1839+
# Test schema migration - MySQL indexes fix (Phase 7)
1840+
# Tests: indexes query excludes PRIMARY key and includes uniqueness info
1841+
- id: 191
1842+
name: 'Schema migration MySQL indexes fix'
1843+
run: 'sling run -d cmd/sling/tests/pipelines/p.25.sm_mysql_indexes_fix.yaml'
1844+
streams: 1
1845+
output_contains:
1846+
- 'Primary key constraints found: 1'
1847+
- 'Indexes found'
18371848
- 'execution succeeded'

core/dbio/templates/mysql.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,16 @@ metadata:
9494
kcu.table_name,
9595
position
9696
97+
# Indexes metadata - excludes PRIMARY key (handled separately by primary_keys)
9798
indexes: |
9899
select
99100
index_name as index_name,
100-
column_name as column_name
101+
column_name as column_name,
102+
CASE WHEN non_unique = 0 THEN 'true' ELSE 'false' END AS is_unique
101103
from information_schema.statistics
102104
where table_schema = '{schema}'
103105
and table_name = '{table}'
106+
and index_name != 'PRIMARY'
104107
order by
105108
index_name,
106109
seq_in_index

0 commit comments

Comments
 (0)