diff --git a/.changeset/mysql-index-byte-bounds.md b/.changeset/mysql-index-byte-bounds.md new file mode 100644 index 0000000000..e47965b932 --- /dev/null +++ b/.changeset/mysql-index-byte-bounds.md @@ -0,0 +1,5 @@ +--- +"better-auth": patch +--- + +Use MySQL's reported byte lengths when validating indexes on existing string columns. diff --git a/e2e/adapter/test/kysely-adapter/adapter.kysely.mysql.test.ts b/e2e/adapter/test/kysely-adapter/adapter.kysely.mysql.test.ts index 29fe7b1c33..bd996acbd3 100644 --- a/e2e/adapter/test/kysely-adapter/adapter.kysely.mysql.test.ts +++ b/e2e/adapter/test/kysely-adapter/adapter.kysely.mysql.test.ts @@ -25,10 +25,52 @@ const kyselyDB = new Kysely({ dialect: new MysqlDialect(mysqlDB), }); -const mysqlDisabledIndexTestSuite = createTestSuite( +const mysqlMigrationIndexTestSuite = createTestSuite( "mysql migration index introspection", {}, () => ({ + /** + * @see https://dev.mysql.com/doc/refman/8.4/en/information-schema-columns-table.html + */ + "uses the column byte length when validating an index": async () => { + const tableName = "mysql_index_byte_length_subject"; + const indexName = "mysql_byte_length_subject_idx"; + const options = { + database: mysqlDB, + plugins: [ + { + id: "mysql-index-byte-length", + schema: { + mysqlIndexByteLengthSubject: { + modelName: tableName, + fields: { + subject: { type: "string" }, + }, + indexes: [{ fields: ["subject"], name: indexName }], + }, + }, + } satisfies BetterAuthPlugin, + ], + } satisfies BetterAuthOptions; + + await mysqlDB.query(` + CREATE TABLE \`${tableName}\` ( + \`id\` varchar(191) NOT NULL, + \`subject\` varchar(1000) CHARACTER SET latin1 NOT NULL, + PRIMARY KEY (\`id\`) + ) ENGINE=InnoDB + `); + try { + const migrations = await getMigrations(options); + expect(await migrations.compileMigrations()).toContain( + `create index \`${indexName}\` on \`${tableName}\` (\`subject\`)`, + ); + await migrations.runMigrations(); + } finally { + await mysqlDB.query(`DROP TABLE \`${tableName}\``); + } + }, + /** * @see https://dev.mysql.com/doc/refman/8.4/en/alter-table.html */ @@ -103,7 +145,7 @@ const { execute } = await testAdapter({ numberIdTestSuite(), joinsTestSuite(), uuidTestSuite(), - mysqlDisabledIndexTestSuite(), + mysqlMigrationIndexTestSuite(), caseInsensitiveTestSuite({ disableTests: { "findOne - eq with mode sensitive (default) should not match different case": true, diff --git a/packages/better-auth/src/db/get-migration.ts b/packages/better-auth/src/db/get-migration.ts index 57313eb187..7e15290a0d 100644 --- a/packages/better-auth/src/db/get-migration.ts +++ b/packages/better-auth/src/db/get-migration.ts @@ -399,7 +399,7 @@ async function getDatabaseColumnBounds( SELECT table_name AS tableName, column_name AS columnName, - character_maximum_length * 4 AS maxIndexBytes + character_octet_length AS maxIndexBytes FROM information_schema.columns WHERE table_schema = DATABASE() `.execute(db)