@@ -18,6 +18,15 @@ interface FetchUniqueConstraintssResult {
1818 type : string ;
1919}
2020
21+ interface FetchUniqueConstraintsFallbackResult {
22+ indexName : string ;
23+ name : string ;
24+ schema : string ;
25+ table : string ;
26+ tableId : string ;
27+ type : string ;
28+ }
29+
2130const FETCH_PRIMARY_KEYS = ( schemas : Array < string > ) => `
2231SELECT
2332 tc.TABLE_SCHEMA AS \`schema\`,
6473 ${ buildSchemaInclusionClause ( schemas , "s.TABLE_SCHEMA" ) }
6574` ;
6675
76+ const FETCH_UNIQUE_CONSTRAINTS_FALLBACK = ( schemas : Array < string > ) => `
77+ SELECT
78+ s.TABLE_SCHEMA AS \`schema\`,
79+ s.TABLE_NAME AS \`table\`,
80+ CONCAT(s.TABLE_SCHEMA, '.', s.TABLE_NAME) AS tableId,
81+ s.COLUMN_NAME AS name,
82+ cols.DATA_TYPE AS type,
83+ s.INDEX_NAME AS \`indexName\`
84+ FROM
85+ information_schema.STATISTICS AS s
86+ JOIN
87+ information_schema.COLUMNS AS cols
88+ ON cols.TABLE_SCHEMA = s.TABLE_SCHEMA
89+ AND cols.TABLE_NAME = s.TABLE_NAME
90+ AND cols.COLUMN_NAME = s.COLUMN_NAME
91+ WHERE
92+ s.NON_UNIQUE = 0 AND
93+ s.INDEX_NAME != 'PRIMARY' AND
94+ cols.IS_NULLABLE = 'NO' AND
95+ ${ buildSchemaInclusionClause ( schemas , "s.TABLE_SCHEMA" ) }
96+ ` ;
97+
6798interface PrimaryKey {
6899 dirty : boolean ;
69100 keys : Array < { name : string ; type : string } > ;
@@ -72,6 +103,36 @@ interface PrimaryKey {
72103 tableId : string ;
73104}
74105
106+ async function isVitess ( client : DatabaseClient ) : Promise < boolean > {
107+ const result = await client . query < { "VERSION()" : string } > (
108+ `SELECT VERSION();` ,
109+ ) ;
110+ return result [ 0 ] [ "VERSION()" ] . includes ( "Vitess" ) ;
111+ }
112+
113+ function processColumnCounts (
114+ results : Array < FetchUniqueConstraintsFallbackResult > ,
115+ ) : Array < FetchUniqueConstraintssResult > {
116+ const indexCountMap : Record < string , number > = { } ;
117+
118+ results . forEach ( ( row ) => {
119+ const indexKey = `${ row . schema } .${ row . table } .${ row . indexName } ` ;
120+ if ( ! indexCountMap [ indexKey ] ) {
121+ indexCountMap [ indexKey ] = 0 ;
122+ }
123+ indexCountMap [ indexKey ] ++ ;
124+ } ) ;
125+
126+ return results . map ( ( row ) => ( {
127+ schema : row . schema ,
128+ table : row . table ,
129+ tableId : row . tableId ,
130+ name : row . name ,
131+ type : row . type ,
132+ columnCount : indexCountMap [ `${ row . schema } .${ row . table } .${ row . indexName } ` ] ,
133+ } ) ) ;
134+ }
135+
75136export async function fetchPrimaryKeys (
76137 client : DatabaseClient ,
77138 schemas : Array < string > ,
@@ -80,9 +141,21 @@ export async function fetchPrimaryKeys(
80141 const primaryKeys = await client . query < FetchPrimaryKeysResult > (
81142 FETCH_PRIMARY_KEYS ( schemas ) ,
82143 ) ;
83- const uniqueConstraints = await client . query < FetchUniqueConstraintssResult > (
84- FETCH_UNIQUE_CONSTRAINTS ( schemas ) ,
85- ) ;
144+ let uniqueConstraints : Array < FetchUniqueConstraintssResult > ;
145+ if ( await isVitess ( client ) ) {
146+ console . log (
147+ "Vitess Mysql Detected - Falling back to fetching unique constraints without window functions" ,
148+ ) ;
149+ const uniqueConstraintsFallback =
150+ await client . query < FetchUniqueConstraintsFallbackResult > (
151+ FETCH_UNIQUE_CONSTRAINTS_FALLBACK ( schemas ) ,
152+ ) ;
153+ uniqueConstraints = processColumnCounts ( uniqueConstraintsFallback ) ;
154+ } else {
155+ uniqueConstraints = await client . query < FetchUniqueConstraintssResult > (
156+ FETCH_UNIQUE_CONSTRAINTS ( schemas ) ,
157+ ) ;
158+ }
86159
87160 // Group all primary keys results together by tableId
88161 const groupedPrimaryKeys = primaryKeys . reduce < typeof results > ( ( acc , row ) => {
@@ -123,6 +196,7 @@ export async function fetchPrimaryKeys(
123196 tableId : row . tableId ,
124197 } ;
125198 }
199+
126200 if (
127201 acc [ row . tableId ] . keys . length === 0 ||
128202 row . columnCount < acc [ row . tableId ] . keys [ 0 ] . name . length
0 commit comments