Skip to content

Commit 2b6c282

Browse files
When Vitess MySQL is detected don't use window funtions (#177)
Co-authored-by: Justin van der Merwe <justnvdm@gmail.com>
1 parent c81d013 commit 2b6c282

3 files changed

Lines changed: 79 additions & 5 deletions

File tree

packages/seed/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@snaplet/seed",
33
"type": "module",
4-
"version": "0.97.17",
4+
"version": "0.97.18",
55
"sideEffects": false,
66
"bin": {
77
"snaplet-seed": "./bin/cli.js"

packages/seed/src/dialects/mysql/introspect/queries/fetchPrimaryKeys.ts

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
2130
const FETCH_PRIMARY_KEYS = (schemas: Array<string>) => `
2231
SELECT
2332
tc.TABLE_SCHEMA AS \`schema\`,
@@ -64,6 +73,28 @@ WHERE
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+
6798
interface 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+
75136
export 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

packages/seed/test/mysql/mysql/createTestDatabase.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const defineCreateTestDb = (state: State) => {
5757
host: url.hostname,
5858
port: parseInt(url.port) || 3306,
5959
user: url.username,
60-
password: url.password ? undefined : url.password,
60+
password: url.password ? url.password : undefined,
6161
database: dbName,
6262
multipleStatements: true,
6363
});

0 commit comments

Comments
 (0)