Skip to content

Commit ca46f80

Browse files
committed
HHH-20056 Cascade delete support detection in TiDB
1 parent 34cc763 commit ca46f80

1 file changed

Lines changed: 62 additions & 24 deletions

File tree

  • hibernate-community-dialects/src/main/java/org/hibernate/community/dialect

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TiDBDialect.java

Lines changed: 62 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
import org.hibernate.sql.model.MutationOperation;
3434
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
3535

36+
import static java.lang.Integer.parseInt;
37+
38+
import static org.hibernate.internal.util.StringHelper.split;
39+
3640
import static org.hibernate.community.dialect.lock.internal.TiDBLockingSupport.TIDB_LOCKING_SUPPORT;
3741

3842
/**
@@ -41,32 +45,59 @@
4145
* @author Cong Wang
4246
*/
4347
public class TiDBDialect extends MySQLDialect {
44-
45-
// 8.0.11 is the first MySQL 8.0 GA release.
46-
// See also: https://docs.pingcap.com/tidb/stable/mysql-compatibility/
47-
private static final DatabaseVersion VERSION80 = DatabaseVersion.make( 8, 0, 11 );
48-
4948
// See also: https://www.pingcap.com/tidb-release-support-policy/
49+
//
50+
// Note this is the minium TiDB version, not the MySQL version TiDB identifies as.
5051
// v5.4 EOL date: 15 Feb 2026
5152
private static final DatabaseVersion MINIMUM_VERSION = DatabaseVersion.make( 5, 4 );
5253

54+
private final DatabaseVersion mySQLVersion;
55+
5356
public TiDBDialect() {
5457
this( MINIMUM_VERSION );
5558
}
5659

5760
public TiDBDialect(DatabaseVersion version) {
5861
super( version );
62+
this.mySQLVersion = DatabaseVersion.make( 8, 0, 11 );
5963
}
6064

6165
public TiDBDialect(DialectResolutionInfo info) {
62-
super( createVersion( info, MINIMUM_VERSION ), MySQLServerConfiguration.fromDialectResolutionInfo( info ) );
66+
super( fetchDataBaseVersion( info ), MySQLServerConfiguration.fromDialectResolutionInfo( info ) );
6367
registerKeywords( info );
68+
this.mySQLVersion = createVersion( info, MINIMUM_VERSION );
69+
}
70+
71+
72+
@Override
73+
public DatabaseVersion determineDatabaseVersion(DialectResolutionInfo info) {
74+
return fetchDataBaseVersion( info );
75+
}
76+
77+
78+
private static DatabaseVersion fetchDataBaseVersion(DialectResolutionInfo info) {
79+
final String versionStringTiDB = info.getDatabaseVersion();
80+
if ( versionStringTiDB != null ) {
81+
// [8, 0, 11, TiDB, v8, 5, 4]
82+
final String[] components = split( ".-", versionStringTiDB );
83+
if ( components.length >= 7 ) {
84+
try {
85+
final int majorVersion = parseInt( components[4].substring(1) ); // v8 -> 8
86+
final int minorVersion = parseInt( components[5] );
87+
final int patchLevel = parseInt( components[6] );
88+
return DatabaseVersion.make( majorVersion, minorVersion, patchLevel );
89+
}
90+
catch (NumberFormatException ex) {
91+
// Ignore
92+
}
93+
}
94+
}
95+
return MINIMUM_VERSION;
6496
}
6597

6698
@Override
6799
public DatabaseVersion getMySQLVersion() {
68-
// For simplicity’s sake, configure MySQL 8.0 compatibility
69-
return VERSION80;
100+
return mySQLVersion;
70101
}
71102

72103
@Override
@@ -77,25 +108,32 @@ protected DatabaseVersion getMinimumSupportedVersion() {
77108
@Override
78109
protected void registerDefaultKeywords() {
79110
super.registerDefaultKeywords();
80-
// TiDB implemented 'Window Functions' of MySQL 8, so the following keywords are reserved.
81-
registerKeyword( "CUME_DIST" );
82-
registerKeyword( "DENSE_RANK" );
83-
registerKeyword( "EXCEPT" );
84-
registerKeyword( "FIRST_VALUE" );
85-
registerKeyword( "GROUPS" );
86-
registerKeyword( "LAG" );
87-
registerKeyword( "LAST_VALUE" );
88-
registerKeyword( "LEAD" );
89-
registerKeyword( "NTH_VALUE" );
90-
registerKeyword( "NTILE" );
91-
registerKeyword( "PERCENT_RANK" );
92-
registerKeyword( "RANK" );
93-
registerKeyword( "ROW_NUMBER" );
111+
112+
if ( getMySQLVersion().isBefore( 8, 0 ) ) {
113+
// TiDB implemented 'Window Functions' of MySQL 8, even in TiDB versions that identify as 5.7
114+
// so the following keywords are reserved.
115+
registerKeyword( "CUME_DIST" );
116+
registerKeyword( "DENSE_RANK" );
117+
registerKeyword( "EXCEPT" );
118+
registerKeyword( "FIRST_VALUE" );
119+
registerKeyword( "GROUPS" );
120+
registerKeyword( "LAG" );
121+
registerKeyword( "LAST_VALUE" );
122+
registerKeyword( "LEAD" );
123+
registerKeyword( "NTH_VALUE" );
124+
registerKeyword( "NTILE" );
125+
registerKeyword( "PERCENT_RANK" );
126+
registerKeyword( "RANK" );
127+
registerKeyword( "ROW_NUMBER" );
128+
}
94129
}
95130

96131
@Override
97132
public boolean supportsCascadeDelete() {
98-
return false;
133+
// FK including cascade is supported as experimental feature since TiDB v6.6.0
134+
// FK including cascade is supported as GA feature since TiDB v8.5.0
135+
// https://docs.pingcap.com/tidb/stable/foreign-key/
136+
return getVersion().isSameOrAfter( 6, 6 );
99137
}
100138

101139
@Override
@@ -146,7 +184,7 @@ protected boolean supportsAliasLocks() {
146184

147185
@Override
148186
public boolean supportsRowValueConstructorSyntaxInInList() {
149-
return getVersion().isSameOrAfter( 5, 7 );
187+
return true;
150188
}
151189

152190
@Override

0 commit comments

Comments
 (0)